Initial commit
Original modules copied with their dependencies DKMS config and makefiles created
This commit is contained in:
commit
434c03501c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.ccls-cache
|
||||
.ccls-cache/*
|
21
README.md
Normal file
21
README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# HP Omen 16 2022 (16-n0000) AMD modules
|
||||
|
||||
This repo contains linux kernel modules that fixes some issues with this model.
|
||||
|
||||
## How to install
|
||||
```bash
|
||||
git clone https://git.rustylab.net/public/omen-modules.git
|
||||
cd omen-modules/<module-name>
|
||||
sudo dkms install .
|
||||
```
|
||||
|
||||
`<module-name>` is one of the follows:
|
||||
- snd_hda_codec_realtek
|
||||
- hp-wmi
|
||||
|
||||
# Special thanks to
|
||||
- [Luis Bocanegra](https://github.com/luisbocanegra) - for giving me a good starting point and guideance at the beginning.
|
||||
- [asus-linux.org](https://asus-linux.org) - for this [post](https://asus-linux.org/blog/sound-2021-01-11/). I gave me basic info on codecs, coeffs, etc.
|
||||
- [joshua stein] - for his amazing [post](https://jcs.org/2018/11/12/vfio) about VFIO, Intel HDA and his [qemu patch](https://github.com/jcs/qemu/compare/e22f675b..jcs-hda-dma) which allowed me do log all neccesary data from drivers
|
||||
- Tomas Espeleta - for [this patch](https://patchwork.kernel.org/project/alsa-devel/patch/20190114200353.4114-1-tomas.espeleta@gmail.com/). It was good example on how to write patches to realtek module
|
||||
- @Lùmi - for bringing my attention to speaker channels mapping problem and motivation to finish audio fix
|
7
hp-wmi/Makefile
Normal file
7
hp-wmi/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
obj-m += hp-wmi.o
|
||||
|
||||
all:
|
||||
make -C /lib/modules/${kernelver}/build M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/${kernelver}/build M=$(PWD) clean
|
6
hp-wmi/dkms.conf
Normal file
6
hp-wmi/dkms.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
BUILT_MODULE_NAME=hp-wmi
|
||||
BUILT_MODULE_LOCATION=./
|
||||
DEST_MODULE_LOCATION=/kernel/drivers/platform/x86/
|
||||
PACKAGE_NAME=omen-hp-wmi
|
||||
PACKAGE_VERSION=1.0
|
||||
AUTOINSTALL=yes
|
1723
hp-wmi/hp-wmi.c
Normal file
1723
hp-wmi/hp-wmi.c
Normal file
File diff suppressed because it is too large
Load diff
9
snd_hda_codec_realtek/Makefile
Normal file
9
snd_hda_codec_realtek/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
snd-hda-codec-realtek-objs := patch_realtek.o
|
||||
obj-m += snd-hda-codec-realtek.o
|
||||
EXTRA_CFLAGS=-I$(PWD)/inc
|
||||
|
||||
all:
|
||||
make -C /lib/modules/${kernelver}/build M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/${kernelver}/build M=$(PWD) clean
|
6
snd_hda_codec_realtek/dkms.conf
Normal file
6
snd_hda_codec_realtek/dkms.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
BUILT_MODULE_NAME=snd-hda-codec-realtek
|
||||
BUILT_MODULE_LOCATION=./
|
||||
DEST_MODULE_LOCATION=/kernel/sound/pci/hda/
|
||||
PACKAGE_NAME=omen-snd-hda-codec-realtek
|
||||
PACKAGE_VERSION=1.0
|
||||
AUTOINSTALL=yes
|
115
snd_hda_codec_realtek/inc/hda_auto_parser.h
Normal file
115
snd_hda_codec_realtek/inc/hda_auto_parser.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* BIOS auto-parser helper functions for HD-audio
|
||||
*
|
||||
* Copyright (c) 2012 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_HDA_AUTO_PARSER_H
|
||||
#define __SOUND_HDA_AUTO_PARSER_H
|
||||
|
||||
/*
|
||||
* Helper for automatic pin configuration
|
||||
*/
|
||||
|
||||
enum {
|
||||
AUTO_PIN_MIC,
|
||||
AUTO_PIN_LINE_IN,
|
||||
AUTO_PIN_CD,
|
||||
AUTO_PIN_AUX,
|
||||
AUTO_PIN_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
AUTO_PIN_LINE_OUT,
|
||||
AUTO_PIN_SPEAKER_OUT,
|
||||
AUTO_PIN_HP_OUT
|
||||
};
|
||||
|
||||
#define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS
|
||||
#define AUTO_CFG_MAX_INS 18
|
||||
|
||||
struct auto_pin_cfg_item {
|
||||
hda_nid_t pin;
|
||||
int type;
|
||||
unsigned int is_headset_mic:1;
|
||||
unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */
|
||||
unsigned int has_boost_on_pin:1;
|
||||
};
|
||||
|
||||
struct auto_pin_cfg;
|
||||
const char *hda_get_autocfg_input_label(struct hda_codec *codec,
|
||||
const struct auto_pin_cfg *cfg,
|
||||
int input);
|
||||
int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
|
||||
const struct auto_pin_cfg *cfg,
|
||||
char *label, int maxlen, int *indexp);
|
||||
|
||||
enum {
|
||||
INPUT_PIN_ATTR_UNUSED, /* pin not connected */
|
||||
INPUT_PIN_ATTR_INT, /* internal mic/line-in */
|
||||
INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */
|
||||
INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */
|
||||
INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */
|
||||
INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */
|
||||
INPUT_PIN_ATTR_LAST = INPUT_PIN_ATTR_FRONT,
|
||||
};
|
||||
|
||||
int snd_hda_get_input_pin_attr(unsigned int def_conf);
|
||||
|
||||
struct auto_pin_cfg {
|
||||
int line_outs;
|
||||
/* sorted in the order of Front/Surr/CLFE/Side */
|
||||
hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS];
|
||||
int speaker_outs;
|
||||
hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS];
|
||||
int hp_outs;
|
||||
int line_out_type; /* AUTO_PIN_XXX_OUT */
|
||||
hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
|
||||
int num_inputs;
|
||||
struct auto_pin_cfg_item inputs[AUTO_CFG_MAX_INS];
|
||||
int dig_outs;
|
||||
hda_nid_t dig_out_pins[2];
|
||||
hda_nid_t dig_in_pin;
|
||||
hda_nid_t mono_out_pin;
|
||||
int dig_out_type[2]; /* HDA_PCM_TYPE_XXX */
|
||||
int dig_in_type; /* HDA_PCM_TYPE_XXX */
|
||||
};
|
||||
|
||||
/* bit-flags for snd_hda_parse_pin_def_config() behavior */
|
||||
#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
|
||||
#define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */
|
||||
#define HDA_PINCFG_HEADSET_MIC (1 << 2) /* Try to find headset mic; mark seq number as 0xc to trigger */
|
||||
#define HDA_PINCFG_HEADPHONE_MIC (1 << 3) /* Try to find headphone mic; mark seq number as 0xd to trigger */
|
||||
|
||||
int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
|
||||
struct auto_pin_cfg *cfg,
|
||||
const hda_nid_t *ignore_nids,
|
||||
unsigned int cond_flags);
|
||||
|
||||
/* older function */
|
||||
#define snd_hda_parse_pin_def_config(codec, cfg, ignore) \
|
||||
snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0)
|
||||
|
||||
static inline int auto_cfg_hp_outs(const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
return (cfg->line_out_type == AUTO_PIN_HP_OUT) ?
|
||||
cfg->line_outs : cfg->hp_outs;
|
||||
}
|
||||
static inline const hda_nid_t *auto_cfg_hp_pins(const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
return (cfg->line_out_type == AUTO_PIN_HP_OUT) ?
|
||||
cfg->line_out_pins : cfg->hp_pins;
|
||||
}
|
||||
static inline int auto_cfg_speaker_outs(const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
return (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) ?
|
||||
cfg->line_outs : cfg->speaker_outs;
|
||||
}
|
||||
static inline const hda_nid_t *auto_cfg_speaker_pins(const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
return (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) ?
|
||||
cfg->line_out_pins : cfg->speaker_pins;
|
||||
}
|
||||
|
||||
#endif /* __SOUND_HDA_AUTO_PARSER_H */
|
19
snd_hda_codec_realtek/inc/hda_component.h
Normal file
19
snd_hda_codec_realtek/inc/hda_component.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* HD audio Component Binding Interface
|
||||
*
|
||||
* Copyright (C) 2021 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/component.h>
|
||||
|
||||
#define HDA_MAX_COMPONENTS 4
|
||||
#define HDA_MAX_NAME_SIZE 50
|
||||
|
||||
struct hda_component {
|
||||
struct device *dev;
|
||||
char name[HDA_MAX_NAME_SIZE];
|
||||
struct hda_codec *codec;
|
||||
void (*playback_hook)(struct device *dev, int action);
|
||||
};
|
356
snd_hda_codec_realtek/inc/hda_generic.h
Normal file
356
snd_hda_codec_realtek/inc/hda_generic.h
Normal file
|
@ -0,0 +1,356 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Generic BIOS auto-parser helper functions for HD-audio
|
||||
*
|
||||
* Copyright (c) 2012 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_HDA_GENERIC_H
|
||||
#define __SOUND_HDA_GENERIC_H
|
||||
|
||||
#include <linux/leds.h>
|
||||
|
||||
/* table entry for multi-io paths */
|
||||
struct hda_multi_io {
|
||||
hda_nid_t pin; /* multi-io widget pin NID */
|
||||
hda_nid_t dac; /* DAC to be connected */
|
||||
unsigned int ctl_in; /* cached input-pin control value */
|
||||
};
|
||||
|
||||
/* Widget connection path
|
||||
*
|
||||
* For output, stored in the order of DAC -> ... -> pin,
|
||||
* for input, pin -> ... -> ADC.
|
||||
*
|
||||
* idx[i] contains the source index number to select on of the widget path[i];
|
||||
* e.g. idx[1] is the index of the DAC (path[0]) selected by path[1] widget
|
||||
* multi[] indicates whether it's a selector widget with multi-connectors
|
||||
* (i.e. the connection selection is mandatory)
|
||||
* vol_ctl and mute_ctl contains the NIDs for the assigned mixers
|
||||
*/
|
||||
|
||||
#define MAX_NID_PATH_DEPTH 10
|
||||
|
||||
enum {
|
||||
NID_PATH_VOL_CTL,
|
||||
NID_PATH_MUTE_CTL,
|
||||
NID_PATH_BOOST_CTL,
|
||||
NID_PATH_NUM_CTLS
|
||||
};
|
||||
|
||||
struct nid_path {
|
||||
int depth;
|
||||
hda_nid_t path[MAX_NID_PATH_DEPTH];
|
||||
unsigned char idx[MAX_NID_PATH_DEPTH];
|
||||
unsigned char multi[MAX_NID_PATH_DEPTH];
|
||||
unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
|
||||
bool active:1; /* activated by driver */
|
||||
bool pin_enabled:1; /* pins are enabled */
|
||||
bool pin_fixed:1; /* path with fixed pin */
|
||||
bool stream_enabled:1; /* stream is active */
|
||||
};
|
||||
|
||||
/* mic/line-in auto switching entry */
|
||||
|
||||
#define MAX_AUTO_MIC_PINS 3
|
||||
|
||||
struct automic_entry {
|
||||
hda_nid_t pin; /* pin */
|
||||
int idx; /* imux index, -1 = invalid */
|
||||
unsigned int attr; /* pin attribute (INPUT_PIN_ATTR_*) */
|
||||
};
|
||||
|
||||
/* active stream id */
|
||||
enum { STREAM_MULTI_OUT, STREAM_INDEP_HP };
|
||||
|
||||
/* PCM hook action */
|
||||
enum {
|
||||
HDA_GEN_PCM_ACT_OPEN,
|
||||
HDA_GEN_PCM_ACT_PREPARE,
|
||||
HDA_GEN_PCM_ACT_CLEANUP,
|
||||
HDA_GEN_PCM_ACT_CLOSE,
|
||||
};
|
||||
|
||||
/* DAC assignment badness table */
|
||||
struct badness_table {
|
||||
int no_primary_dac; /* no primary DAC */
|
||||
int no_dac; /* no secondary DACs */
|
||||
int shared_primary; /* primary DAC is shared with main output */
|
||||
int shared_surr; /* secondary DAC shared with main or primary */
|
||||
int shared_clfe; /* third DAC shared with main or primary */
|
||||
int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
|
||||
};
|
||||
|
||||
extern const struct badness_table hda_main_out_badness;
|
||||
extern const struct badness_table hda_extra_out_badness;
|
||||
|
||||
struct hda_gen_spec {
|
||||
char stream_name_analog[32]; /* analog PCM stream */
|
||||
const struct hda_pcm_stream *stream_analog_playback;
|
||||
const struct hda_pcm_stream *stream_analog_capture;
|
||||
|
||||
char stream_name_alt_analog[32]; /* alternative analog PCM stream */
|
||||
const struct hda_pcm_stream *stream_analog_alt_playback;
|
||||
const struct hda_pcm_stream *stream_analog_alt_capture;
|
||||
|
||||
char stream_name_digital[32]; /* digital PCM stream */
|
||||
const struct hda_pcm_stream *stream_digital_playback;
|
||||
const struct hda_pcm_stream *stream_digital_capture;
|
||||
|
||||
/* PCM */
|
||||
unsigned int active_streams;
|
||||
struct mutex pcm_mutex;
|
||||
|
||||
/* playback */
|
||||
struct hda_multi_out multiout; /* playback set-up
|
||||
* max_channels, dacs must be set
|
||||
* dig_out_nid and hp_nid are optional
|
||||
*/
|
||||
hda_nid_t alt_dac_nid;
|
||||
hda_nid_t follower_dig_outs[3]; /* optional - for auto-parsing */
|
||||
int dig_out_type;
|
||||
|
||||
/* capture */
|
||||
unsigned int num_adc_nids;
|
||||
hda_nid_t adc_nids[AUTO_CFG_MAX_INS];
|
||||
hda_nid_t dig_in_nid; /* digital-in NID; optional */
|
||||
hda_nid_t mixer_nid; /* analog-mixer NID */
|
||||
hda_nid_t mixer_merge_nid; /* aamix merge-point NID (optional) */
|
||||
const char *input_labels[HDA_MAX_NUM_INPUTS];
|
||||
int input_label_idxs[HDA_MAX_NUM_INPUTS];
|
||||
|
||||
/* capture setup for dynamic dual-adc switch */
|
||||
hda_nid_t cur_adc;
|
||||
unsigned int cur_adc_stream_tag;
|
||||
unsigned int cur_adc_format;
|
||||
|
||||
/* capture source */
|
||||
struct hda_input_mux input_mux;
|
||||
unsigned int cur_mux[3];
|
||||
|
||||
/* channel model */
|
||||
/* min_channel_count contains the minimum channel count for primary
|
||||
* outputs. When multi_ios is set, the channels can be configured
|
||||
* between min_channel_count and (min_channel_count + multi_ios * 2).
|
||||
*
|
||||
* ext_channel_count contains the current channel count of the primary
|
||||
* out. This varies in the range above.
|
||||
*
|
||||
* Meanwhile, const_channel_count is the channel count for all outputs
|
||||
* including headphone and speakers. It's a constant value, and the
|
||||
* PCM is set up as max(ext_channel_count, const_channel_count).
|
||||
*/
|
||||
int min_channel_count; /* min. channel count for primary out */
|
||||
int ext_channel_count; /* current channel count for primary */
|
||||
int const_channel_count; /* channel count for all */
|
||||
|
||||
/* PCM information */
|
||||
struct hda_pcm *pcm_rec[3]; /* used in build_pcms() */
|
||||
|
||||
/* dynamic controls, init_verbs and input_mux */
|
||||
struct auto_pin_cfg autocfg;
|
||||
struct snd_array kctls;
|
||||
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
|
||||
hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
|
||||
unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
|
||||
/* shared hp/mic */
|
||||
hda_nid_t shared_mic_vref_pin;
|
||||
hda_nid_t hp_mic_pin;
|
||||
int hp_mic_mux_idx;
|
||||
|
||||
/* DAC/ADC lists */
|
||||
int num_all_dacs;
|
||||
hda_nid_t all_dacs[16];
|
||||
int num_all_adcs;
|
||||
hda_nid_t all_adcs[AUTO_CFG_MAX_INS];
|
||||
|
||||
/* path list */
|
||||
struct snd_array paths;
|
||||
|
||||
/* path indices */
|
||||
int out_paths[AUTO_CFG_MAX_OUTS];
|
||||
int hp_paths[AUTO_CFG_MAX_OUTS];
|
||||
int speaker_paths[AUTO_CFG_MAX_OUTS];
|
||||
int aamix_out_paths[3];
|
||||
int digout_paths[AUTO_CFG_MAX_OUTS];
|
||||
int input_paths[HDA_MAX_NUM_INPUTS][AUTO_CFG_MAX_INS];
|
||||
int loopback_paths[HDA_MAX_NUM_INPUTS];
|
||||
int loopback_merge_path;
|
||||
int digin_path;
|
||||
|
||||
/* auto-mic stuff */
|
||||
int am_num_entries;
|
||||
struct automic_entry am_entry[MAX_AUTO_MIC_PINS];
|
||||
|
||||
/* for pin sensing */
|
||||
/* current status; set in hda_generic.c */
|
||||
unsigned int hp_jack_present:1;
|
||||
unsigned int line_jack_present:1;
|
||||
unsigned int speaker_muted:1; /* current status of speaker mute */
|
||||
unsigned int line_out_muted:1; /* current status of LO mute */
|
||||
|
||||
/* internal states of automute / autoswitch behavior */
|
||||
unsigned int auto_mic:1;
|
||||
unsigned int automute_speaker:1; /* automute speaker outputs */
|
||||
unsigned int automute_lo:1; /* automute LO outputs */
|
||||
|
||||
/* capabilities detected by parser */
|
||||
unsigned int detect_hp:1; /* Headphone detection enabled */
|
||||
unsigned int detect_lo:1; /* Line-out detection enabled */
|
||||
unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
|
||||
unsigned int automute_lo_possible:1; /* there are line outs and HP */
|
||||
|
||||
/* additional parameters set by codec drivers */
|
||||
unsigned int master_mute:1; /* master mute over all */
|
||||
unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
|
||||
unsigned int line_in_auto_switch:1; /* allow line-in auto switch */
|
||||
unsigned int auto_mute_via_amp:1; /* auto-mute via amp instead of pinctl */
|
||||
|
||||
/* parser behavior flags; set before snd_hda_gen_parse_auto_config() */
|
||||
unsigned int suppress_auto_mute:1; /* suppress input jack auto mute */
|
||||
unsigned int suppress_auto_mic:1; /* suppress input jack auto switch */
|
||||
|
||||
/* other parse behavior flags */
|
||||
unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */
|
||||
unsigned int hp_mic:1; /* Allow HP as a mic-in */
|
||||
unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */
|
||||
unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
|
||||
unsigned int no_multi_io:1; /* Don't try multi I/O config */
|
||||
unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
|
||||
unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
|
||||
unsigned int own_eapd_ctl:1; /* set EAPD by own function */
|
||||
unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */
|
||||
unsigned int vmaster_mute_led:1; /* add SPK-LED flag to vmaster mute switch */
|
||||
unsigned int mic_mute_led:1; /* add MIC-LED flag to capture mute switch */
|
||||
unsigned int indep_hp:1; /* independent HP supported */
|
||||
unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
|
||||
unsigned int add_stereo_mix_input:2; /* add aamix as a capture src */
|
||||
unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
|
||||
unsigned int power_down_unused:1; /* power down unused widgets */
|
||||
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
||||
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
||||
unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
|
||||
|
||||
/* other internal flags */
|
||||
unsigned int no_analog:1; /* digital I/O only */
|
||||
unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
|
||||
unsigned int indep_hp_enabled:1; /* independent HP enabled */
|
||||
unsigned int have_aamix_ctl:1;
|
||||
unsigned int hp_mic_jack_modes:1;
|
||||
unsigned int skip_verbs:1; /* don't apply verbs at snd_hda_gen_init() */
|
||||
|
||||
/* additional mute flags (only effective with auto_mute_via_amp=1) */
|
||||
u64 mute_bits;
|
||||
|
||||
/* bitmask for skipping volume controls */
|
||||
u64 out_vol_mask;
|
||||
|
||||
/* badness tables for output path evaluations */
|
||||
const struct badness_table *main_out_badness;
|
||||
const struct badness_table *extra_out_badness;
|
||||
|
||||
/* preferred pin/DAC pairs; an array of paired NIDs */
|
||||
const hda_nid_t *preferred_dacs;
|
||||
|
||||
/* loopback mixing mode */
|
||||
bool aamix_mode;
|
||||
|
||||
/* digital beep */
|
||||
hda_nid_t beep_nid;
|
||||
|
||||
/* for virtual master */
|
||||
hda_nid_t vmaster_nid;
|
||||
unsigned int vmaster_tlv[4];
|
||||
struct hda_vmaster_mute_hook vmaster_mute;
|
||||
|
||||
struct hda_loopback_check loopback;
|
||||
struct snd_array loopback_list;
|
||||
|
||||
/* multi-io */
|
||||
int multi_ios;
|
||||
struct hda_multi_io multi_io[4];
|
||||
|
||||
/* hooks */
|
||||
void (*init_hook)(struct hda_codec *codec);
|
||||
void (*automute_hook)(struct hda_codec *codec);
|
||||
void (*cap_sync_hook)(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
/* PCM hooks */
|
||||
void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
struct snd_pcm_substream *substream,
|
||||
int action);
|
||||
void (*pcm_capture_hook)(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
struct snd_pcm_substream *substream,
|
||||
int action);
|
||||
|
||||
/* automute / autoswitch hooks */
|
||||
void (*hp_automute_hook)(struct hda_codec *codec,
|
||||
struct hda_jack_callback *cb);
|
||||
void (*line_automute_hook)(struct hda_codec *codec,
|
||||
struct hda_jack_callback *cb);
|
||||
void (*mic_autoswitch_hook)(struct hda_codec *codec,
|
||||
struct hda_jack_callback *cb);
|
||||
|
||||
/* leds */
|
||||
struct led_classdev *led_cdevs[NUM_AUDIO_LEDS];
|
||||
};
|
||||
|
||||
/* values for add_stereo_mix_input flag */
|
||||
enum {
|
||||
HDA_HINT_STEREO_MIX_DISABLE, /* No stereo mix input */
|
||||
HDA_HINT_STEREO_MIX_ENABLE, /* Add stereo mix input */
|
||||
HDA_HINT_STEREO_MIX_AUTO, /* Add only if auto-mic is disabled */
|
||||
};
|
||||
|
||||
int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
|
||||
|
||||
int snd_hda_gen_init(struct hda_codec *codec);
|
||||
void snd_hda_gen_free(struct hda_codec *codec);
|
||||
|
||||
int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path);
|
||||
struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx);
|
||||
struct nid_path *
|
||||
snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
|
||||
hda_nid_t to_nid, int anchor_nid);
|
||||
void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
|
||||
bool enable, bool add_aamix);
|
||||
|
||||
struct snd_kcontrol_new *
|
||||
snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
|
||||
const struct snd_kcontrol_new *temp);
|
||||
|
||||
int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||
struct auto_pin_cfg *cfg);
|
||||
int snd_hda_gen_build_controls(struct hda_codec *codec);
|
||||
int snd_hda_gen_build_pcms(struct hda_codec *codec);
|
||||
|
||||
/* standard jack event callbacks */
|
||||
void snd_hda_gen_hp_automute(struct hda_codec *codec,
|
||||
struct hda_jack_callback *jack);
|
||||
void snd_hda_gen_line_automute(struct hda_codec *codec,
|
||||
struct hda_jack_callback *jack);
|
||||
void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
|
||||
struct hda_jack_callback *jack);
|
||||
void snd_hda_gen_update_outputs(struct hda_codec *codec);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
||||
#endif
|
||||
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state);
|
||||
void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
|
||||
int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
|
||||
|
||||
int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
|
||||
int (*callback)(struct led_classdev *,
|
||||
enum led_brightness));
|
||||
int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
|
||||
int (*callback)(struct led_classdev *,
|
||||
enum led_brightness));
|
||||
|
||||
#endif /* __SOUND_HDA_GENERIC_H */
|
2848
snd_hda_codec_realtek/inc/hda_intel.c
Normal file
2848
snd_hda_codec_realtek/inc/hda_intel.c
Normal file
File diff suppressed because it is too large
Load diff
195
snd_hda_codec_realtek/inc/hda_jack.h
Normal file
195
snd_hda_codec_realtek/inc/hda_jack.h
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Jack-detection handling for HD-audio
|
||||
*
|
||||
* Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_HDA_JACK_H
|
||||
#define __SOUND_HDA_JACK_H
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <sound/jack.h>
|
||||
|
||||
struct auto_pin_cfg;
|
||||
struct hda_jack_tbl;
|
||||
struct hda_jack_callback;
|
||||
|
||||
typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
|
||||
|
||||
struct hda_jack_callback {
|
||||
hda_nid_t nid;
|
||||
int dev_id;
|
||||
hda_jack_callback_fn func;
|
||||
unsigned int private_data; /* arbitrary data */
|
||||
unsigned int unsol_res; /* unsolicited event bits */
|
||||
struct hda_jack_tbl *jack; /* associated jack entry */
|
||||
struct hda_jack_callback *next;
|
||||
};
|
||||
|
||||
struct hda_jack_tbl {
|
||||
hda_nid_t nid;
|
||||
int dev_id;
|
||||
unsigned char tag; /* unsol event tag */
|
||||
struct hda_jack_callback *callback;
|
||||
/* jack-detection stuff */
|
||||
unsigned int pin_sense; /* cached pin-sense value */
|
||||
unsigned int jack_detect:1; /* capable of jack-detection? */
|
||||
unsigned int jack_dirty:1; /* needs to update? */
|
||||
unsigned int phantom_jack:1; /* a fixed, always present port? */
|
||||
unsigned int block_report:1; /* in a transitional state - do not report to userspace */
|
||||
hda_nid_t gating_jack; /* valid when gating jack plugged */
|
||||
hda_nid_t gated_jack; /* gated is dependent on this jack */
|
||||
hda_nid_t key_report_jack; /* key reports to this jack */
|
||||
int type;
|
||||
int button_state;
|
||||
struct snd_jack *jack;
|
||||
};
|
||||
|
||||
struct hda_jack_keymap {
|
||||
enum snd_jack_types type;
|
||||
int key;
|
||||
};
|
||||
|
||||
struct hda_jack_tbl *
|
||||
snd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_tbl_get - query the jack-table entry for the given NID
|
||||
* @codec: the HDA codec
|
||||
* @nid: pin NID to refer to
|
||||
*/
|
||||
static inline struct hda_jack_tbl *
|
||||
snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return snd_hda_jack_tbl_get_mst(codec, nid, 0);
|
||||
}
|
||||
|
||||
struct hda_jack_tbl *
|
||||
snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec,
|
||||
unsigned char tag, int dev_id);
|
||||
|
||||
void snd_hda_jack_tbl_disconnect(struct hda_codec *codec);
|
||||
void snd_hda_jack_tbl_clear(struct hda_codec *codec);
|
||||
|
||||
void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
|
||||
|
||||
int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dev_id);
|
||||
|
||||
struct hda_jack_callback *
|
||||
snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dev_id, hda_jack_callback_fn func);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect_enable - enable the jack-detection
|
||||
* @codec: the HDA codec
|
||||
* @nid: pin NID to enable
|
||||
* @func: callback function to register
|
||||
*
|
||||
* In the case of error, the return value will be a pointer embedded with
|
||||
* errno. Check and handle the return value appropriately with standard
|
||||
* macros such as @IS_ERR() and @PTR_ERR().
|
||||
*/
|
||||
static inline struct hda_jack_callback *
|
||||
snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
|
||||
hda_jack_callback_fn cb)
|
||||
{
|
||||
return snd_hda_jack_detect_enable_callback_mst(codec, nid, 0, cb);
|
||||
}
|
||||
|
||||
int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
|
||||
hda_nid_t gating_nid);
|
||||
|
||||
int snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid,
|
||||
const struct hda_jack_keymap *keymap,
|
||||
hda_nid_t jack_nid);
|
||||
|
||||
void snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid,
|
||||
int button_state);
|
||||
|
||||
u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id);
|
||||
|
||||
/* the jack state returned from snd_hda_jack_detect_state() */
|
||||
enum {
|
||||
HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
|
||||
};
|
||||
|
||||
int snd_hda_jack_detect_state_mst(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dev_id);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect_state - query pin Presence Detect status
|
||||
* @codec: the CODEC to sense
|
||||
* @nid: the pin NID to sense
|
||||
*
|
||||
* Query and return the pin's Presence Detect status, as either
|
||||
* HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return snd_hda_jack_detect_state_mst(codec, nid, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect_mst - Detect the jack
|
||||
* @codec: the HDA codec
|
||||
* @nid: pin NID to check jack detection
|
||||
* @dev_id: pin device entry id
|
||||
*/
|
||||
static inline bool
|
||||
snd_hda_jack_detect_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id)
|
||||
{
|
||||
return snd_hda_jack_detect_state_mst(codec, nid, dev_id) !=
|
||||
HDA_JACK_NOT_PRESENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect - Detect the jack
|
||||
* @codec: the HDA codec
|
||||
* @nid: pin NID to check jack detection
|
||||
*/
|
||||
static inline bool
|
||||
snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return snd_hda_jack_detect_mst(codec, nid, 0);
|
||||
}
|
||||
|
||||
bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
|
||||
|
||||
int snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dev_id, const char *name, bool phantom_jack,
|
||||
int type, const struct hda_jack_keymap *keymap);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_add_kctl - Add a kctl for the given pin
|
||||
* @codec: the HDA codec
|
||||
* @nid: pin NID to assign
|
||||
* @name: string name for the jack
|
||||
* @phantom_jack: flag to deal as a phantom jack
|
||||
* @type: jack type bits to be reported, 0 for guessing from pincfg
|
||||
* @keymap: optional jack / key mapping
|
||||
*
|
||||
* This assigns a jack-detection kctl to the given pin. The kcontrol
|
||||
* will have the given name and index.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
const char *name, bool phantom_jack,
|
||||
int type, const struct hda_jack_keymap *keymap)
|
||||
{
|
||||
return snd_hda_jack_add_kctl_mst(codec, nid, 0,
|
||||
name, phantom_jack, type, keymap);
|
||||
}
|
||||
|
||||
int snd_hda_jack_add_kctls(struct hda_codec *codec,
|
||||
const struct auto_pin_cfg *cfg);
|
||||
|
||||
void snd_hda_jack_report_sync(struct hda_codec *codec);
|
||||
|
||||
void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res);
|
||||
|
||||
void snd_hda_jack_poll_all(struct hda_codec *codec);
|
||||
|
||||
#endif /* __SOUND_HDA_JACK_H */
|
737
snd_hda_codec_realtek/inc/hda_local.h
Normal file
737
snd_hda_codec_realtek/inc/hda_local.h
Normal file
|
@ -0,0 +1,737 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Universal Interface for Intel High Definition Audio Codec
|
||||
*
|
||||
* Local helper functions
|
||||
*
|
||||
* Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_HDA_LOCAL_H
|
||||
#define __SOUND_HDA_LOCAL_H
|
||||
|
||||
/* We abuse kcontrol_new.subdev field to pass the NID corresponding to
|
||||
* the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG,
|
||||
* snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID.
|
||||
*
|
||||
* Note that the subdevice field is cleared again before the real registration
|
||||
* in snd_hda_ctl_add(), so that this value won't appear in the outside.
|
||||
*/
|
||||
#define HDA_SUBDEV_NID_FLAG (1U << 31)
|
||||
#define HDA_SUBDEV_AMP_FLAG (1U << 30)
|
||||
|
||||
/*
|
||||
* for mixer controls
|
||||
*/
|
||||
#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
|
||||
((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
|
||||
#define HDA_AMP_VAL_MIN_MUTE (1<<29)
|
||||
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
|
||||
HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
|
||||
/* mono volume with index (index=0,1,...) (channel=1,2) */
|
||||
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir, flags) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
|
||||
.subdevice = HDA_SUBDEV_AMP_FLAG, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
|
||||
.info = snd_hda_mixer_amp_volume_info, \
|
||||
.get = snd_hda_mixer_amp_volume_get, \
|
||||
.put = snd_hda_mixer_amp_volume_put, \
|
||||
.tlv = { .c = snd_hda_mixer_amp_tlv }, \
|
||||
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir) | flags }
|
||||
/* stereo volume with index */
|
||||
#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
|
||||
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction, 0)
|
||||
/* mono volume */
|
||||
#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
|
||||
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction, 0)
|
||||
/* stereo volume */
|
||||
#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
|
||||
HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
|
||||
/* stereo volume with min=mute */
|
||||
#define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \
|
||||
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \
|
||||
HDA_AMP_VAL_MIN_MUTE)
|
||||
/* mono mute switch with index (index=0,1,...) (channel=1,2) */
|
||||
#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
|
||||
.subdevice = HDA_SUBDEV_AMP_FLAG, \
|
||||
.info = snd_hda_mixer_amp_switch_info, \
|
||||
.get = snd_hda_mixer_amp_switch_get, \
|
||||
.put = snd_hda_mixer_amp_switch_put, \
|
||||
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
|
||||
/* stereo mute switch with index */
|
||||
#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
|
||||
HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
|
||||
/* mono mute switch */
|
||||
#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
|
||||
HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
|
||||
/* stereo mute switch */
|
||||
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
|
||||
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
|
||||
#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
|
||||
.subdevice = HDA_SUBDEV_AMP_FLAG, \
|
||||
.info = snd_hda_mixer_amp_switch_info, \
|
||||
.get = snd_hda_mixer_amp_switch_get_beep, \
|
||||
.put = snd_hda_mixer_amp_switch_put_beep, \
|
||||
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
|
||||
#else
|
||||
/* no digital beep - just the standard one */
|
||||
#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, ch, xidx, dir) \
|
||||
HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, ch, xidx, dir)
|
||||
#endif /* CONFIG_SND_HDA_INPUT_BEEP */
|
||||
/* special beep mono mute switch */
|
||||
#define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
|
||||
HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, 0, nid, channel, xindex, direction)
|
||||
/* special beep stereo mute switch */
|
||||
#define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
|
||||
HDA_CODEC_MUTE_BEEP_MONO(xname, nid, 3, xindex, direction)
|
||||
|
||||
extern const char *snd_hda_pcm_type_name[];
|
||||
|
||||
int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
|
||||
unsigned int size, unsigned int __user *_tlv);
|
||||
int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
#endif
|
||||
/* lowlevel accessor with caching; use carefully */
|
||||
#define snd_hda_codec_amp_read(codec, nid, ch, dir, idx) \
|
||||
snd_hdac_regmap_get_amp(&(codec)->core, nid, ch, dir, idx)
|
||||
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
|
||||
int ch, int dir, int idx, int mask, int val);
|
||||
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
|
||||
int direction, int idx, int mask, int val);
|
||||
int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
|
||||
int direction, int idx, int mask, int val);
|
||||
int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dir, int idx, int mask, int val);
|
||||
void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
|
||||
unsigned int *tlv);
|
||||
struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
|
||||
const char *name);
|
||||
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||
unsigned int *tlv, const char * const *followers,
|
||||
const char *suffix, bool init_follower_vol,
|
||||
unsigned int access, struct snd_kcontrol **ctl_ret);
|
||||
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \
|
||||
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL)
|
||||
int snd_hda_codec_reset(struct hda_codec *codec);
|
||||
void snd_hda_codec_disconnect_pcms(struct hda_codec *codec);
|
||||
|
||||
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
||||
|
||||
struct hda_vmaster_mute_hook {
|
||||
/* below two fields must be filled by the caller of
|
||||
* snd_hda_add_vmaster_hook() beforehand
|
||||
*/
|
||||
struct snd_kcontrol *sw_kctl;
|
||||
void (*hook)(void *, int);
|
||||
/* below are initialized automatically */
|
||||
struct hda_codec *codec;
|
||||
};
|
||||
|
||||
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
||||
struct hda_vmaster_mute_hook *hook);
|
||||
void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
|
||||
|
||||
/* amp value bits */
|
||||
#define HDA_AMP_MUTE 0x80
|
||||
#define HDA_AMP_UNMUTE 0x00
|
||||
#define HDA_AMP_VOLMASK 0x7f
|
||||
|
||||
/*
|
||||
* SPDIF I/O
|
||||
*/
|
||||
int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
|
||||
hda_nid_t associated_nid,
|
||||
hda_nid_t cvt_nid, int type);
|
||||
#define snd_hda_create_spdif_out_ctls(codec, anid, cnid) \
|
||||
snd_hda_create_dig_out_ctls(codec, anid, cnid, HDA_PCM_TYPE_SPDIF)
|
||||
int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
|
||||
|
||||
/*
|
||||
* input MUX helper
|
||||
*/
|
||||
#define HDA_MAX_NUM_INPUTS 36
|
||||
struct hda_input_mux_item {
|
||||
char label[32];
|
||||
unsigned int index;
|
||||
};
|
||||
struct hda_input_mux {
|
||||
unsigned int num_items;
|
||||
struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
|
||||
};
|
||||
|
||||
int snd_hda_input_mux_info(const struct hda_input_mux *imux,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_hda_input_mux_put(struct hda_codec *codec,
|
||||
const struct hda_input_mux *imux,
|
||||
struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
|
||||
unsigned int *cur_val);
|
||||
int snd_hda_add_imux_item(struct hda_codec *codec,
|
||||
struct hda_input_mux *imux, const char *label,
|
||||
int index, int *type_idx);
|
||||
|
||||
/*
|
||||
* Multi-channel / digital-out PCM helper
|
||||
*/
|
||||
|
||||
enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
|
||||
enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
|
||||
|
||||
#define HDA_MAX_OUTS 5
|
||||
|
||||
struct hda_multi_out {
|
||||
int num_dacs; /* # of DACs, must be more than 1 */
|
||||
const hda_nid_t *dac_nids; /* DAC list */
|
||||
hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
|
||||
hda_nid_t hp_out_nid[HDA_MAX_OUTS]; /* DACs for multiple HPs */
|
||||
hda_nid_t extra_out_nid[HDA_MAX_OUTS]; /* other (e.g. speaker) DACs */
|
||||
hda_nid_t dig_out_nid; /* digital out audio widget */
|
||||
const hda_nid_t *follower_dig_outs;
|
||||
int max_channels; /* currently supported analog channels */
|
||||
int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
|
||||
int no_share_stream; /* don't share a stream with multiple pins */
|
||||
int share_spdif; /* share SPDIF pin */
|
||||
/* PCM information for both analog and SPDIF DACs */
|
||||
unsigned int analog_rates;
|
||||
unsigned int analog_maxbps;
|
||||
u64 analog_formats;
|
||||
unsigned int spdif_rates;
|
||||
unsigned int spdif_maxbps;
|
||||
u64 spdif_formats;
|
||||
};
|
||||
|
||||
int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_dig_open(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_dig_close(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout);
|
||||
int snd_hda_multi_out_analog_open(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct hda_pcm_stream *hinfo);
|
||||
int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout,
|
||||
unsigned int stream_tag,
|
||||
unsigned int format,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
|
||||
struct hda_multi_out *mout);
|
||||
|
||||
/*
|
||||
* generic proc interface
|
||||
*/
|
||||
#ifdef CONFIG_SND_PROC_FS
|
||||
int snd_hda_codec_proc_new(struct hda_codec *codec);
|
||||
#else
|
||||
static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
|
||||
#endif
|
||||
|
||||
#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
|
||||
void snd_print_pcm_bits(int pcm, char *buf, int buflen);
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
int snd_hda_add_new_ctls(struct hda_codec *codec,
|
||||
const struct snd_kcontrol_new *knew);
|
||||
|
||||
/*
|
||||
* Fix-up pin default configurations and add default verbs
|
||||
*/
|
||||
|
||||
struct hda_pintbl {
|
||||
hda_nid_t nid;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct hda_model_fixup {
|
||||
const int id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct hda_fixup {
|
||||
int type;
|
||||
bool chained:1; /* call the chained fixup(s) after this */
|
||||
bool chained_before:1; /* call the chained fixup(s) before this */
|
||||
int chain_id;
|
||||
union {
|
||||
const struct hda_pintbl *pins;
|
||||
const struct hda_verb *verbs;
|
||||
void (*func)(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix,
|
||||
int action);
|
||||
} v;
|
||||
};
|
||||
|
||||
struct snd_hda_pin_quirk {
|
||||
unsigned int codec; /* Codec vendor/device ID */
|
||||
unsigned short subvendor; /* PCI subvendor ID */
|
||||
const struct hda_pintbl *pins; /* list of matching pins */
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
const char *name;
|
||||
#endif
|
||||
int value; /* quirk value */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
|
||||
#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
|
||||
{ .codec = _codec,\
|
||||
.subvendor = _subvendor,\
|
||||
.name = _name,\
|
||||
.value = _value,\
|
||||
.pins = (const struct hda_pintbl[]) { _pins, {0, 0}} \
|
||||
}
|
||||
#else
|
||||
|
||||
#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
|
||||
{ .codec = _codec,\
|
||||
.subvendor = _subvendor,\
|
||||
.value = _value,\
|
||||
.pins = (const struct hda_pintbl[]) { _pins, {0, 0}} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define HDA_FIXUP_ID_NOT_SET -1
|
||||
#define HDA_FIXUP_ID_NO_FIXUP -2
|
||||
|
||||
/* fixup types */
|
||||
enum {
|
||||
HDA_FIXUP_INVALID,
|
||||
HDA_FIXUP_PINS,
|
||||
HDA_FIXUP_VERBS,
|
||||
HDA_FIXUP_FUNC,
|
||||
HDA_FIXUP_PINCTLS,
|
||||
};
|
||||
|
||||
/* fixup action definitions */
|
||||
enum {
|
||||
HDA_FIXUP_ACT_PRE_PROBE,
|
||||
HDA_FIXUP_ACT_PROBE,
|
||||
HDA_FIXUP_ACT_INIT,
|
||||
HDA_FIXUP_ACT_BUILD,
|
||||
HDA_FIXUP_ACT_FREE,
|
||||
};
|
||||
|
||||
int snd_hda_add_verbs(struct hda_codec *codec, const struct hda_verb *list);
|
||||
void snd_hda_apply_verbs(struct hda_codec *codec);
|
||||
void snd_hda_apply_pincfgs(struct hda_codec *codec,
|
||||
const struct hda_pintbl *cfg);
|
||||
void snd_hda_apply_fixup(struct hda_codec *codec, int action);
|
||||
void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth);
|
||||
void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
const struct hda_model_fixup *models,
|
||||
const struct snd_pci_quirk *quirk,
|
||||
const struct hda_fixup *fixlist);
|
||||
void snd_hda_pick_pin_fixup(struct hda_codec *codec,
|
||||
const struct snd_hda_pin_quirk *pin_quirk,
|
||||
const struct hda_fixup *fixlist,
|
||||
bool match_all_pins);
|
||||
|
||||
/* helper macros to retrieve pin default-config values */
|
||||
#define get_defcfg_connect(cfg) \
|
||||
((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
|
||||
#define get_defcfg_association(cfg) \
|
||||
((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
|
||||
#define get_defcfg_location(cfg) \
|
||||
((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
|
||||
#define get_defcfg_sequence(cfg) \
|
||||
(cfg & AC_DEFCFG_SEQUENCE)
|
||||
#define get_defcfg_device(cfg) \
|
||||
((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
|
||||
#define get_defcfg_misc(cfg) \
|
||||
((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
|
||||
|
||||
/* amp values */
|
||||
#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
|
||||
#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
|
||||
#define AMP_OUT_MUTE 0xb080
|
||||
#define AMP_OUT_UNMUTE 0xb000
|
||||
#define AMP_OUT_ZERO 0xb000
|
||||
/* pinctl values */
|
||||
#define PIN_IN (AC_PINCTL_IN_EN)
|
||||
#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
|
||||
#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
|
||||
#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
|
||||
#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
|
||||
#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
|
||||
#define PIN_OUT (AC_PINCTL_OUT_EN)
|
||||
#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
|
||||
#define PIN_HP_AMP (AC_PINCTL_HP_EN)
|
||||
|
||||
unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
|
||||
unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
|
||||
hda_nid_t pin, unsigned int val);
|
||||
int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
|
||||
unsigned int val, bool cached);
|
||||
|
||||
/**
|
||||
* _snd_hda_set_pin_ctl - Set a pin-control value safely
|
||||
* @codec: the codec instance
|
||||
* @pin: the pin NID to set the control
|
||||
* @val: the pin-control value (AC_PINCTL_* bits)
|
||||
*
|
||||
* This function sets the pin-control value to the given pin, but
|
||||
* filters out the invalid pin-control bits when the pin has no such
|
||||
* capabilities. For example, when PIN_HP is passed but the pin has no
|
||||
* HP-drive capability, the HP bit is omitted.
|
||||
*
|
||||
* The function doesn't check the input VREF capability bits, though.
|
||||
* Use snd_hda_get_default_vref() to guess the right value.
|
||||
* Also, this function is only for analog pins, not for HDMI pins.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val)
|
||||
{
|
||||
return _snd_hda_set_pin_ctl(codec, pin, val, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_set_pin_ctl_cache - Set a pin-control value safely
|
||||
* @codec: the codec instance
|
||||
* @pin: the pin NID to set the control
|
||||
* @val: the pin-control value (AC_PINCTL_* bits)
|
||||
*
|
||||
* Just like snd_hda_set_pin_ctl() but write to cache as well.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_set_pin_ctl_cache(struct hda_codec *codec, hda_nid_t pin,
|
||||
unsigned int val)
|
||||
{
|
||||
return _snd_hda_set_pin_ctl(codec, pin, val, true);
|
||||
}
|
||||
|
||||
int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid);
|
||||
int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int val);
|
||||
|
||||
#define for_each_hda_codec_node(nid, codec) \
|
||||
for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++)
|
||||
|
||||
/* Set the codec power_state flag to indicate to allow unsol event handling;
|
||||
* see hda_codec_unsol_event() in hda_bind.c. Calling this might confuse the
|
||||
* state tracking, so use with care.
|
||||
*/
|
||||
static inline void snd_hda_codec_allow_unsol_events(struct hda_codec *codec)
|
||||
{
|
||||
codec->core.dev.power.power_state = PMSG_ON;
|
||||
}
|
||||
|
||||
/*
|
||||
* get widget capabilities
|
||||
*/
|
||||
static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
if (nid < codec->core.start_nid ||
|
||||
nid >= codec->core.start_nid + codec->core.num_nodes)
|
||||
return 0;
|
||||
return codec->wcaps[nid - codec->core.start_nid];
|
||||
}
|
||||
|
||||
/* get the widget type from widget capability bits */
|
||||
static inline int get_wcaps_type(unsigned int wcaps)
|
||||
{
|
||||
if (!wcaps)
|
||||
return -1; /* invalid type */
|
||||
return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int get_wcaps_channels(u32 wcaps)
|
||||
{
|
||||
unsigned int chans;
|
||||
|
||||
chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
|
||||
chans = ((chans << 1) | 1) + 1;
|
||||
|
||||
return chans;
|
||||
}
|
||||
|
||||
static inline void snd_hda_override_wcaps(struct hda_codec *codec,
|
||||
hda_nid_t nid, u32 val)
|
||||
{
|
||||
if (nid >= codec->core.start_nid &&
|
||||
nid < codec->core.start_nid + codec->core.num_nodes)
|
||||
codec->wcaps[nid - codec->core.start_nid] = val;
|
||||
}
|
||||
|
||||
u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
|
||||
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
|
||||
unsigned int caps);
|
||||
/**
|
||||
* snd_hda_query_pin_caps - Query PIN capabilities
|
||||
* @codec: the HD-auio codec
|
||||
* @nid: the NID to query
|
||||
*
|
||||
* Query PIN capabilities for the given widget.
|
||||
* Returns the obtained capability bits.
|
||||
*
|
||||
* When cap bits have been already read, this doesn't read again but
|
||||
* returns the cached value.
|
||||
*/
|
||||
static inline u32
|
||||
snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_override_pin_caps - Override the pin capabilities
|
||||
* @codec: the CODEC
|
||||
* @nid: the NID to override
|
||||
* @caps: the capability bits to set
|
||||
*
|
||||
* Override the cached PIN capabilitiy bits value by the given one.
|
||||
*
|
||||
* Returns zero if successful or a negative error code.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int caps)
|
||||
{
|
||||
return snd_hdac_override_parm(&codec->core, nid, AC_PAR_PIN_CAP, caps);
|
||||
}
|
||||
|
||||
bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
|
||||
int dir, unsigned int bits);
|
||||
|
||||
#define nid_has_mute(codec, nid, dir) \
|
||||
snd_hda_check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
|
||||
#define nid_has_volume(codec, nid, dir) \
|
||||
snd_hda_check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
|
||||
|
||||
|
||||
/* flags for hda_nid_item */
|
||||
#define HDA_NID_ITEM_AMP (1<<0)
|
||||
|
||||
struct hda_nid_item {
|
||||
struct snd_kcontrol *kctl;
|
||||
unsigned int index;
|
||||
hda_nid_t nid;
|
||||
unsigned short flags;
|
||||
};
|
||||
|
||||
int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
|
||||
struct snd_kcontrol *kctl);
|
||||
int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
|
||||
unsigned int index, hda_nid_t nid);
|
||||
void snd_hda_ctls_clear(struct hda_codec *codec);
|
||||
|
||||
/*
|
||||
* hwdep interface
|
||||
*/
|
||||
#ifdef CONFIG_SND_HDA_HWDEP
|
||||
int snd_hda_create_hwdep(struct hda_codec *codec);
|
||||
#else
|
||||
static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
|
||||
#endif
|
||||
|
||||
void snd_hda_sysfs_init(struct hda_codec *codec);
|
||||
void snd_hda_sysfs_clear(struct hda_codec *codec);
|
||||
|
||||
extern const struct attribute_group *snd_hda_dev_attr_groups[];
|
||||
|
||||
#ifdef CONFIG_SND_HDA_RECONFIG
|
||||
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key);
|
||||
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);
|
||||
int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp);
|
||||
#else
|
||||
static inline
|
||||
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline
|
||||
int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* power-management
|
||||
*/
|
||||
|
||||
void snd_hda_schedule_power_save(struct hda_codec *codec);
|
||||
|
||||
struct hda_amp_list {
|
||||
hda_nid_t nid;
|
||||
unsigned char dir;
|
||||
unsigned char idx;
|
||||
};
|
||||
|
||||
struct hda_loopback_check {
|
||||
const struct hda_amp_list *amplist;
|
||||
int power_on;
|
||||
};
|
||||
|
||||
int snd_hda_check_amp_list_power(struct hda_codec *codec,
|
||||
struct hda_loopback_check *check,
|
||||
hda_nid_t nid);
|
||||
|
||||
/* check whether the actual power state matches with the target state */
|
||||
static inline bool
|
||||
snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int target_state)
|
||||
{
|
||||
return snd_hdac_check_power_state(&codec->core, nid, target_state);
|
||||
}
|
||||
|
||||
static inline unsigned int snd_hda_sync_power_state(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int target_state)
|
||||
{
|
||||
return snd_hdac_sync_power_state(&codec->core, nid, target_state);
|
||||
}
|
||||
unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state);
|
||||
|
||||
void snd_hda_codec_shutdown(struct hda_codec *codec);
|
||||
|
||||
/*
|
||||
* AMP control callbacks
|
||||
*/
|
||||
/* retrieve parameters from private_value */
|
||||
#define get_amp_nid_(pv) ((pv) & 0xffff)
|
||||
#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
|
||||
#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
|
||||
#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
|
||||
#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
|
||||
#define get_amp_index_(pv) (((pv) >> 19) & 0xf)
|
||||
#define get_amp_index(kc) get_amp_index_((kc)->private_value)
|
||||
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
|
||||
#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
|
||||
|
||||
/*
|
||||
* enum control helper
|
||||
*/
|
||||
int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo,
|
||||
int num_items, const char * const *texts);
|
||||
#define snd_hda_enum_bool_helper_info(kcontrol, uinfo) \
|
||||
snd_hda_enum_helper_info(kcontrol, uinfo, 0, NULL)
|
||||
|
||||
/*
|
||||
* CEA Short Audio Descriptor data
|
||||
*/
|
||||
struct cea_sad {
|
||||
int channels;
|
||||
int format; /* (format == 0) indicates invalid SAD */
|
||||
int rates;
|
||||
int sample_bits; /* for LPCM */
|
||||
int max_bitrate; /* for AC3...ATRAC */
|
||||
int profile; /* for WMAPRO */
|
||||
};
|
||||
|
||||
#define ELD_FIXED_BYTES 20
|
||||
#define ELD_MAX_SIZE 256
|
||||
#define ELD_MAX_MNL 16
|
||||
#define ELD_MAX_SAD 16
|
||||
|
||||
/*
|
||||
* ELD: EDID Like Data
|
||||
*/
|
||||
struct parsed_hdmi_eld {
|
||||
/*
|
||||
* all fields will be cleared before updating ELD
|
||||
*/
|
||||
int baseline_len;
|
||||
int eld_ver;
|
||||
int cea_edid_ver;
|
||||
char monitor_name[ELD_MAX_MNL + 1];
|
||||
int manufacture_id;
|
||||
int product_id;
|
||||
u64 port_id;
|
||||
int support_hdcp;
|
||||
int support_ai;
|
||||
int conn_type;
|
||||
int aud_synch_delay;
|
||||
int spk_alloc;
|
||||
int sad_count;
|
||||
struct cea_sad sad[ELD_MAX_SAD];
|
||||
};
|
||||
|
||||
struct hdmi_eld {
|
||||
bool monitor_present;
|
||||
bool eld_valid;
|
||||
int eld_size;
|
||||
char eld_buffer[ELD_MAX_SIZE];
|
||||
struct parsed_hdmi_eld info;
|
||||
};
|
||||
|
||||
int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
|
||||
int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned char *buf, int *eld_size);
|
||||
int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e,
|
||||
const unsigned char *buf, int size);
|
||||
void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e);
|
||||
void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
|
||||
struct hda_pcm_stream *hinfo);
|
||||
|
||||
int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned char *buf, int *eld_size,
|
||||
bool rev3_or_later);
|
||||
|
||||
#ifdef CONFIG_SND_PROC_FS
|
||||
void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
|
||||
struct snd_info_buffer *buffer,
|
||||
hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid);
|
||||
void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
|
||||
struct snd_info_buffer *buffer);
|
||||
#endif
|
||||
|
||||
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
|
||||
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
|
||||
|
||||
void snd_hda_codec_display_power(struct hda_codec *codec, bool enable);
|
||||
|
||||
/*
|
||||
*/
|
||||
#define codec_err(codec, fmt, args...) \
|
||||
dev_err(hda_codec_dev(codec), fmt, ##args)
|
||||
#define codec_warn(codec, fmt, args...) \
|
||||
dev_warn(hda_codec_dev(codec), fmt, ##args)
|
||||
#define codec_info(codec, fmt, args...) \
|
||||
dev_info(hda_codec_dev(codec), fmt, ##args)
|
||||
#define codec_dbg(codec, fmt, args...) \
|
||||
dev_dbg(hda_codec_dev(codec), fmt, ##args)
|
||||
|
||||
#endif /* __SOUND_HDA_LOCAL_H */
|
95
snd_hda_codec_realtek/inc/hp_x360_helper.c
Normal file
95
snd_hda_codec_realtek/inc/hp_x360_helper.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Fixes for HP X360 laptops with top B&O speakers
|
||||
* to be included from codec driver
|
||||
*/
|
||||
|
||||
static void alc295_fixup_hp_top_speakers(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
static const struct hda_pintbl pincfgs[] = {
|
||||
{ 0x17, 0x90170110 },
|
||||
{ }
|
||||
};
|
||||
static const struct coef_fw alc295_hp_speakers_coefs[] = {
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0000), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003f), WRITE_COEF(0x28, 0x1000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0004), WRITE_COEF(0x28, 0x0600), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0006), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0xc0c0), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0008), WRITE_COEF(0x28, 0xb000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x002e), WRITE_COEF(0x28, 0x0800), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x00c1), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x0320), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0039), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003b), WRITE_COEF(0x28, 0xffff), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003c), WRITE_COEF(0x28, 0xffd0), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0080), WRITE_COEF(0x28, 0x0880), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x0dfe), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0018), WRITE_COEF(0x28, 0x0219), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x005d), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x9142), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c0), WRITE_COEF(0x28, 0x01ce), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c1), WRITE_COEF(0x28, 0xed0c), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c2), WRITE_COEF(0x28, 0x1c00), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c3), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c4), WRITE_COEF(0x28, 0x0200), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c5), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c6), WRITE_COEF(0x28, 0x0399), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c7), WRITE_COEF(0x28, 0x2330), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c8), WRITE_COEF(0x28, 0x1e5d), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c9), WRITE_COEF(0x28, 0x6eff), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00ca), WRITE_COEF(0x28, 0x01c0), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cb), WRITE_COEF(0x28, 0xed0c), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cc), WRITE_COEF(0x28, 0x1c00), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cd), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00ce), WRITE_COEF(0x28, 0x0200), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cf), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d0), WRITE_COEF(0x28, 0x0399), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d1), WRITE_COEF(0x28, 0x2330), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d2), WRITE_COEF(0x28, 0x1e5d), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d3), WRITE_COEF(0x28, 0x6eff), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0062), WRITE_COEF(0x28, 0x8000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0063), WRITE_COEF(0x28, 0x5f5f), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0064), WRITE_COEF(0x28, 0x1000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0065), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0066), WRITE_COEF(0x28, 0x4004), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0067), WRITE_COEF(0x28, 0x0802), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0068), WRITE_COEF(0x28, 0x890f), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0069), WRITE_COEF(0x28, 0xe021), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0070), WRITE_COEF(0x28, 0x8012), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0071), WRITE_COEF(0x28, 0x3450), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0072), WRITE_COEF(0x28, 0x0123), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0073), WRITE_COEF(0x28, 0x4543), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0074), WRITE_COEF(0x28, 0x2100), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0075), WRITE_COEF(0x28, 0x4321), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0076), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0050), WRITE_COEF(0x28, 0x8200), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0051), WRITE_COEF(0x28, 0x0707), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0052), WRITE_COEF(0x28, 0x4090), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0090), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x721f), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0012), WRITE_COEF(0x28, 0xebeb), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x009e), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0060), WRITE_COEF(0x28, 0x2213), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0006), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003f), WRITE_COEF(0x28, 0x3000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0004), WRITE_COEF(0x28, 0x0500), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0040), WRITE_COEF(0x28, 0x800c), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0046), WRITE_COEF(0x28, 0xc22e), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x004b), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024),
|
||||
WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0050), WRITE_COEF(0x28, 0x82ec), WRITE_COEF(0x29, 0xb024),
|
||||
};
|
||||
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
snd_hda_apply_pincfgs(codec, pincfgs);
|
||||
alc295_fixup_disable_dac3(codec, fix, action);
|
||||
break;
|
||||
case HDA_FIXUP_ACT_INIT:
|
||||
alc_process_coef_fw(codec, alc295_hp_speakers_coefs);
|
||||
break;
|
||||
}
|
||||
}
|
492
snd_hda_codec_realtek/inc/ideapad_s740_helper.c
Normal file
492
snd_hda_codec_realtek/inc/ideapad_s740_helper.c
Normal file
|
@ -0,0 +1,492 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Fixes for Lenovo Ideapad S740, to be included from codec driver */
|
||||
|
||||
static const struct hda_verb alc285_ideapad_s740_coefs[] = {
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||
{}
|
||||
};
|
||||
|
||||
static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix,
|
||||
int action)
|
||||
{
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs);
|
||||
break;
|
||||
}
|
||||
}
|
36
snd_hda_codec_realtek/inc/thinkpad_helper.c
Normal file
36
snd_hda_codec_realtek/inc/thinkpad_helper.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Helper functions for Thinkpad LED control;
|
||||
* to be included from codec driver
|
||||
*/
|
||||
|
||||
#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
static bool is_thinkpad(struct hda_codec *codec)
|
||||
{
|
||||
return (codec->core.subsystem_id >> 16 == 0x17aa) &&
|
||||
(acpi_dev_found("LEN0068") || acpi_dev_found("LEN0268") ||
|
||||
acpi_dev_found("IBM0068"));
|
||||
}
|
||||
|
||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
if (!is_thinkpad(codec))
|
||||
return;
|
||||
snd_hda_gen_add_mute_led_cdev(codec, NULL);
|
||||
snd_hda_gen_add_micmute_led_cdev(codec, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* CONFIG_THINKPAD_ACPI */
|
||||
|
||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_THINKPAD_ACPI */
|
12244
snd_hda_codec_realtek/patch_realtek.c
Normal file
12244
snd_hda_codec_realtek/patch_realtek.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue