162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Universal Interface for Intel High Definition Audio Codec 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef __SOUND_HDA_CODEC_H 962306a36Sopenharmony_ci#define __SOUND_HDA_CODEC_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/refcount.h> 1262306a36Sopenharmony_ci#include <linux/mod_devicetable.h> 1362306a36Sopenharmony_ci#include <sound/info.h> 1462306a36Sopenharmony_ci#include <sound/control.h> 1562306a36Sopenharmony_ci#include <sound/pcm.h> 1662306a36Sopenharmony_ci#include <sound/hwdep.h> 1762306a36Sopenharmony_ci#include <sound/hdaudio.h> 1862306a36Sopenharmony_ci#include <sound/hda_verbs.h> 1962306a36Sopenharmony_ci#include <sound/hda_regmap.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * Structures 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistruct hda_bus; 2662306a36Sopenharmony_cistruct hda_beep; 2762306a36Sopenharmony_cistruct hda_codec; 2862306a36Sopenharmony_cistruct hda_pcm; 2962306a36Sopenharmony_cistruct hda_pcm_stream; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * codec bus 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * each controller needs to creata a hda_bus to assign the accessor. 3562306a36Sopenharmony_ci * A hda_bus contains several codecs in the list codec_list. 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_cistruct hda_bus { 3862306a36Sopenharmony_ci struct hdac_bus core; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci struct snd_card *card; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci struct pci_dev *pci; 4362306a36Sopenharmony_ci const char *modelname; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci struct mutex prepare_mutex; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* assigned PCMs */ 4862306a36Sopenharmony_ci DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* misc op flags */ 5162306a36Sopenharmony_ci unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */ 5262306a36Sopenharmony_ci /* status for codec/controller */ 5362306a36Sopenharmony_ci unsigned int shutdown :1; /* being unloaded */ 5462306a36Sopenharmony_ci unsigned int response_reset:1; /* controller was reset */ 5562306a36Sopenharmony_ci unsigned int in_reset:1; /* during reset operation */ 5662306a36Sopenharmony_ci unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ 5762306a36Sopenharmony_ci unsigned int bus_probing :1; /* during probing process */ 5862306a36Sopenharmony_ci unsigned int keep_power:1; /* keep power up for notification */ 5962306a36Sopenharmony_ci unsigned int jackpoll_in_suspend:1; /* keep jack polling during 6062306a36Sopenharmony_ci * runtime suspend 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci int primary_dig_out_type; /* primary digital out PCM type */ 6462306a36Sopenharmony_ci unsigned int mixer_assigned; /* codec addr for mixer name */ 6562306a36Sopenharmony_ci}; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* from hdac_bus to hda_bus */ 6862306a36Sopenharmony_ci#define to_hda_bus(bus) container_of(bus, struct hda_bus, core) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * codec preset 7262306a36Sopenharmony_ci * 7362306a36Sopenharmony_ci * Known codecs have the patch to build and set up the controls/PCMs 7462306a36Sopenharmony_ci * better than the generic parser. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_citypedef int (*hda_codec_patch_t)(struct hda_codec *); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define HDA_CODEC_ID_SKIP_PROBE 0x00000001 7962306a36Sopenharmony_ci#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 8062306a36Sopenharmony_ci#define HDA_CODEC_ID_GENERIC 0x00000201 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \ 8362306a36Sopenharmony_ci { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \ 8462306a36Sopenharmony_ci .api_version = HDA_DEV_LEGACY, \ 8562306a36Sopenharmony_ci .driver_data = (unsigned long)(_patch) } 8662306a36Sopenharmony_ci#define HDA_CODEC_ENTRY(_vid, _name, _patch) \ 8762306a36Sopenharmony_ci HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch) 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistruct hda_codec_driver { 9062306a36Sopenharmony_ci struct hdac_driver core; 9162306a36Sopenharmony_ci const struct hda_device_id *id; 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ciint __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, 9562306a36Sopenharmony_ci struct module *owner); 9662306a36Sopenharmony_ci#define hda_codec_driver_register(drv) \ 9762306a36Sopenharmony_ci __hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE) 9862306a36Sopenharmony_civoid hda_codec_driver_unregister(struct hda_codec_driver *drv); 9962306a36Sopenharmony_ci#define module_hda_codec_driver(drv) \ 10062306a36Sopenharmony_ci module_driver(drv, hda_codec_driver_register, \ 10162306a36Sopenharmony_ci hda_codec_driver_unregister) 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/* ops set by the preset patch */ 10462306a36Sopenharmony_cistruct hda_codec_ops { 10562306a36Sopenharmony_ci int (*build_controls)(struct hda_codec *codec); 10662306a36Sopenharmony_ci int (*build_pcms)(struct hda_codec *codec); 10762306a36Sopenharmony_ci int (*init)(struct hda_codec *codec); 10862306a36Sopenharmony_ci void (*free)(struct hda_codec *codec); 10962306a36Sopenharmony_ci void (*unsol_event)(struct hda_codec *codec, unsigned int res); 11062306a36Sopenharmony_ci void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg, 11162306a36Sopenharmony_ci unsigned int power_state); 11262306a36Sopenharmony_ci#ifdef CONFIG_PM 11362306a36Sopenharmony_ci int (*suspend)(struct hda_codec *codec); 11462306a36Sopenharmony_ci int (*resume)(struct hda_codec *codec); 11562306a36Sopenharmony_ci int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); 11662306a36Sopenharmony_ci#endif 11762306a36Sopenharmony_ci void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on); 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* PCM callbacks */ 12162306a36Sopenharmony_cistruct hda_pcm_ops { 12262306a36Sopenharmony_ci int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, 12362306a36Sopenharmony_ci struct snd_pcm_substream *substream); 12462306a36Sopenharmony_ci int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec, 12562306a36Sopenharmony_ci struct snd_pcm_substream *substream); 12662306a36Sopenharmony_ci int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec, 12762306a36Sopenharmony_ci unsigned int stream_tag, unsigned int format, 12862306a36Sopenharmony_ci struct snd_pcm_substream *substream); 12962306a36Sopenharmony_ci int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, 13062306a36Sopenharmony_ci struct snd_pcm_substream *substream); 13162306a36Sopenharmony_ci unsigned int (*get_delay)(struct hda_pcm_stream *info, 13262306a36Sopenharmony_ci struct hda_codec *codec, 13362306a36Sopenharmony_ci struct snd_pcm_substream *substream); 13462306a36Sopenharmony_ci}; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/* PCM information for each substream */ 13762306a36Sopenharmony_cistruct hda_pcm_stream { 13862306a36Sopenharmony_ci unsigned int substreams; /* number of substreams, 0 = not exist*/ 13962306a36Sopenharmony_ci unsigned int channels_min; /* min. number of channels */ 14062306a36Sopenharmony_ci unsigned int channels_max; /* max. number of channels */ 14162306a36Sopenharmony_ci hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */ 14262306a36Sopenharmony_ci u32 rates; /* supported rates */ 14362306a36Sopenharmony_ci u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */ 14462306a36Sopenharmony_ci unsigned int maxbps; /* supported max. bit per sample */ 14562306a36Sopenharmony_ci const struct snd_pcm_chmap_elem *chmap; /* chmap to override */ 14662306a36Sopenharmony_ci struct hda_pcm_ops ops; 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/* PCM types */ 15062306a36Sopenharmony_cienum { 15162306a36Sopenharmony_ci HDA_PCM_TYPE_AUDIO, 15262306a36Sopenharmony_ci HDA_PCM_TYPE_SPDIF, 15362306a36Sopenharmony_ci HDA_PCM_TYPE_HDMI, 15462306a36Sopenharmony_ci HDA_PCM_TYPE_MODEM, 15562306a36Sopenharmony_ci HDA_PCM_NTYPES 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci#define SNDRV_PCM_INVALID_DEVICE (-1) 15962306a36Sopenharmony_ci/* for PCM creation */ 16062306a36Sopenharmony_cistruct hda_pcm { 16162306a36Sopenharmony_ci char *name; 16262306a36Sopenharmony_ci struct hda_pcm_stream stream[2]; 16362306a36Sopenharmony_ci unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */ 16462306a36Sopenharmony_ci int device; /* device number to assign */ 16562306a36Sopenharmony_ci struct snd_pcm *pcm; /* assigned PCM instance */ 16662306a36Sopenharmony_ci bool own_chmap; /* codec driver provides own channel maps */ 16762306a36Sopenharmony_ci /* private: */ 16862306a36Sopenharmony_ci struct hda_codec *codec; 16962306a36Sopenharmony_ci struct list_head list; 17062306a36Sopenharmony_ci unsigned int disconnected:1; 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/* codec information */ 17462306a36Sopenharmony_cistruct hda_codec { 17562306a36Sopenharmony_ci struct hdac_device core; 17662306a36Sopenharmony_ci struct hda_bus *bus; 17762306a36Sopenharmony_ci struct snd_card *card; 17862306a36Sopenharmony_ci unsigned int addr; /* codec addr*/ 17962306a36Sopenharmony_ci u32 probe_id; /* overridden id for probing */ 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci /* detected preset */ 18262306a36Sopenharmony_ci const struct hda_device_id *preset; 18362306a36Sopenharmony_ci const char *modelname; /* model name for preset */ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci /* set by patch */ 18662306a36Sopenharmony_ci struct hda_codec_ops patch_ops; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci /* PCM to create, set by patch_ops.build_pcms callback */ 18962306a36Sopenharmony_ci struct list_head pcm_list_head; 19062306a36Sopenharmony_ci refcount_t pcm_ref; 19162306a36Sopenharmony_ci wait_queue_head_t remove_sleep; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* codec specific info */ 19462306a36Sopenharmony_ci void *spec; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci /* beep device */ 19762306a36Sopenharmony_ci struct hda_beep *beep; 19862306a36Sopenharmony_ci unsigned int beep_mode; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* widget capabilities cache */ 20162306a36Sopenharmony_ci u32 *wcaps; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci struct snd_array mixers; /* list of assigned mixer elements */ 20462306a36Sopenharmony_ci struct snd_array nids; /* list of mapped mixer elements */ 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci struct list_head conn_list; /* linked-list of connection-list */ 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci struct mutex spdif_mutex; 20962306a36Sopenharmony_ci struct mutex control_mutex; 21062306a36Sopenharmony_ci struct snd_array spdif_out; 21162306a36Sopenharmony_ci unsigned int spdif_in_enable; /* SPDIF input enable? */ 21262306a36Sopenharmony_ci const hda_nid_t *follower_dig_outs; /* optional digital out follower widgets */ 21362306a36Sopenharmony_ci struct snd_array init_pins; /* initial (BIOS) pin configurations */ 21462306a36Sopenharmony_ci struct snd_array driver_pins; /* pin configs set by codec parser */ 21562306a36Sopenharmony_ci struct snd_array cvt_setups; /* audio convert setups */ 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci struct mutex user_mutex; 21862306a36Sopenharmony_ci#ifdef CONFIG_SND_HDA_RECONFIG 21962306a36Sopenharmony_ci struct snd_array init_verbs; /* additional init verbs */ 22062306a36Sopenharmony_ci struct snd_array hints; /* additional hints */ 22162306a36Sopenharmony_ci struct snd_array user_pins; /* default pin configs to override */ 22262306a36Sopenharmony_ci#endif 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci#ifdef CONFIG_SND_HDA_HWDEP 22562306a36Sopenharmony_ci struct snd_hwdep *hwdep; /* assigned hwdep device */ 22662306a36Sopenharmony_ci#endif 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci /* misc flags */ 22962306a36Sopenharmony_ci unsigned int configured:1; /* codec was configured */ 23062306a36Sopenharmony_ci unsigned int in_freeing:1; /* being released */ 23162306a36Sopenharmony_ci unsigned int display_power_control:1; /* needs display power */ 23262306a36Sopenharmony_ci unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each 23362306a36Sopenharmony_ci * status change 23462306a36Sopenharmony_ci * (e.g. Realtek codecs) 23562306a36Sopenharmony_ci */ 23662306a36Sopenharmony_ci unsigned int pin_amp_workaround:1; /* pin out-amp takes index 23762306a36Sopenharmony_ci * (e.g. Conexant codecs) 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_ci unsigned int single_adc_amp:1; /* adc in-amp takes no index 24062306a36Sopenharmony_ci * (e.g. CX20549 codec) 24162306a36Sopenharmony_ci */ 24262306a36Sopenharmony_ci unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ 24362306a36Sopenharmony_ci unsigned int pins_shutup:1; /* pins are shut up */ 24462306a36Sopenharmony_ci unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 24562306a36Sopenharmony_ci unsigned int no_jack_detect:1; /* Machine has no jack-detection */ 24662306a36Sopenharmony_ci unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */ 24762306a36Sopenharmony_ci unsigned int inv_jack_detect:1; /* broken h/w: inverted detection bit */ 24862306a36Sopenharmony_ci unsigned int pcm_format_first:1; /* PCM format must be set first */ 24962306a36Sopenharmony_ci unsigned int cached_write:1; /* write only to caches */ 25062306a36Sopenharmony_ci unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ 25162306a36Sopenharmony_ci unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ 25262306a36Sopenharmony_ci unsigned int power_save_node:1; /* advanced PM for each widget */ 25362306a36Sopenharmony_ci unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */ 25462306a36Sopenharmony_ci unsigned int force_pin_prefix:1; /* Add location prefix */ 25562306a36Sopenharmony_ci unsigned int link_down_at_suspend:1; /* link down at runtime suspend */ 25662306a36Sopenharmony_ci unsigned int relaxed_resume:1; /* don't resume forcibly for jack */ 25762306a36Sopenharmony_ci unsigned int forced_resume:1; /* forced resume for jack */ 25862306a36Sopenharmony_ci unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */ 25962306a36Sopenharmony_ci unsigned int ctl_dev_id:1; /* old control element id build behaviour */ 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci#ifdef CONFIG_PM 26262306a36Sopenharmony_ci unsigned long power_on_acct; 26362306a36Sopenharmony_ci unsigned long power_off_acct; 26462306a36Sopenharmony_ci unsigned long power_jiffies; 26562306a36Sopenharmony_ci#endif 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci /* filter the requested power state per nid */ 26862306a36Sopenharmony_ci unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid, 26962306a36Sopenharmony_ci unsigned int power_state); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* codec-specific additional proc output */ 27262306a36Sopenharmony_ci void (*proc_widget_hook)(struct snd_info_buffer *buffer, 27362306a36Sopenharmony_ci struct hda_codec *codec, hda_nid_t nid); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci /* jack detection */ 27662306a36Sopenharmony_ci struct snd_array jacktbl; 27762306a36Sopenharmony_ci unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */ 27862306a36Sopenharmony_ci struct delayed_work jackpoll_work; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci int depop_delay; /* depop delay in ms, -1 for default delay time */ 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci /* fix-up list */ 28362306a36Sopenharmony_ci int fixup_id; 28462306a36Sopenharmony_ci const struct hda_fixup *fixup_list; 28562306a36Sopenharmony_ci const char *fixup_name; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* additional init verbs */ 28862306a36Sopenharmony_ci struct snd_array verbs; 28962306a36Sopenharmony_ci}; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci#define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, core.dev) 29262306a36Sopenharmony_ci#define hda_codec_dev(_dev) (&(_dev)->core.dev) 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#define hdac_to_hda_codec(_hdac) container_of(_hdac, struct hda_codec, core) 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci#define list_for_each_codec(c, bus) \ 29762306a36Sopenharmony_ci list_for_each_entry(c, &(bus)->core.codec_list, core.list) 29862306a36Sopenharmony_ci#define list_for_each_codec_safe(c, n, bus) \ 29962306a36Sopenharmony_ci list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list) 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci/* snd_hda_codec_read/write optional flags */ 30262306a36Sopenharmony_ci#define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0) 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/* 30562306a36Sopenharmony_ci * constructors 30662306a36Sopenharmony_ci */ 30762306a36Sopenharmony_ci__printf(3, 4) struct hda_codec * 30862306a36Sopenharmony_cisnd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr, 30962306a36Sopenharmony_ci const char *fmt, ...); 31062306a36Sopenharmony_ciint snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, 31162306a36Sopenharmony_ci unsigned int codec_addr, struct hda_codec **codecp); 31262306a36Sopenharmony_ciint snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, 31362306a36Sopenharmony_ci unsigned int codec_addr, struct hda_codec *codec, 31462306a36Sopenharmony_ci bool snddev_managed); 31562306a36Sopenharmony_ciint snd_hda_codec_configure(struct hda_codec *codec); 31662306a36Sopenharmony_ciint snd_hda_codec_update_widgets(struct hda_codec *codec); 31762306a36Sopenharmony_civoid snd_hda_codec_register(struct hda_codec *codec); 31862306a36Sopenharmony_civoid snd_hda_codec_unregister(struct hda_codec *codec); 31962306a36Sopenharmony_civoid snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci/* 32262306a36Sopenharmony_ci * low level functions 32362306a36Sopenharmony_ci */ 32462306a36Sopenharmony_cistatic inline unsigned int 32562306a36Sopenharmony_cisnd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, 32662306a36Sopenharmony_ci int flags, 32762306a36Sopenharmony_ci unsigned int verb, unsigned int parm) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci return snd_hdac_codec_read(&codec->core, nid, flags, verb, parm); 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic inline int 33362306a36Sopenharmony_cisnd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags, 33462306a36Sopenharmony_ci unsigned int verb, unsigned int parm) 33562306a36Sopenharmony_ci{ 33662306a36Sopenharmony_ci return snd_hdac_codec_write(&codec->core, nid, flags, verb, parm); 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci#define snd_hda_param_read(codec, nid, param) \ 34062306a36Sopenharmony_ci snd_hdac_read_parm(&(codec)->core, nid, param) 34162306a36Sopenharmony_ci#define snd_hda_get_sub_nodes(codec, nid, start_nid) \ 34262306a36Sopenharmony_ci snd_hdac_get_sub_nodes(&(codec)->core, nid, start_nid) 34362306a36Sopenharmony_ciint snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 34462306a36Sopenharmony_ci hda_nid_t *conn_list, int max_conns); 34562306a36Sopenharmony_cistatic inline int 34662306a36Sopenharmony_cisnd_hda_get_num_conns(struct hda_codec *codec, hda_nid_t nid) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci return snd_hda_get_connections(codec, nid, NULL, 0); 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci#define snd_hda_get_raw_connections(codec, nid, list, max_conns) \ 35262306a36Sopenharmony_ci snd_hdac_get_connections(&(codec)->core, nid, list, max_conns) 35362306a36Sopenharmony_ci#define snd_hda_get_num_raw_conns(codec, nid) \ 35462306a36Sopenharmony_ci snd_hdac_get_connections(&(codec)->core, nid, NULL, 0) 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciint snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, 35762306a36Sopenharmony_ci const hda_nid_t **listp); 35862306a36Sopenharmony_ciint snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums, 35962306a36Sopenharmony_ci const hda_nid_t *list); 36062306a36Sopenharmony_ciint snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, 36162306a36Sopenharmony_ci hda_nid_t nid, int recursive); 36262306a36Sopenharmony_ciunsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid); 36362306a36Sopenharmony_ciint snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, 36462306a36Sopenharmony_ci u8 *dev_list, int max_devices); 36562306a36Sopenharmony_ciint snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid); 36662306a36Sopenharmony_ciint snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistruct hda_verb { 36962306a36Sopenharmony_ci hda_nid_t nid; 37062306a36Sopenharmony_ci u32 verb; 37162306a36Sopenharmony_ci u32 param; 37262306a36Sopenharmony_ci}; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_civoid snd_hda_sequence_write(struct hda_codec *codec, 37562306a36Sopenharmony_ci const struct hda_verb *seq); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci/* cached write */ 37862306a36Sopenharmony_cistatic inline int 37962306a36Sopenharmony_cisnd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 38062306a36Sopenharmony_ci int flags, unsigned int verb, unsigned int parm) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci return snd_hdac_regmap_write(&codec->core, nid, verb, parm); 38362306a36Sopenharmony_ci} 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci/* the struct for codec->pin_configs */ 38662306a36Sopenharmony_cistruct hda_pincfg { 38762306a36Sopenharmony_ci hda_nid_t nid; 38862306a36Sopenharmony_ci unsigned char ctrl; /* original pin control value */ 38962306a36Sopenharmony_ci unsigned char target; /* target pin control value */ 39062306a36Sopenharmony_ci unsigned int cfg; /* default configuration */ 39162306a36Sopenharmony_ci}; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ciunsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); 39462306a36Sopenharmony_ciint snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid, 39562306a36Sopenharmony_ci unsigned int cfg); 39662306a36Sopenharmony_ciint snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, 39762306a36Sopenharmony_ci hda_nid_t nid, unsigned int cfg); /* for hwdep */ 39862306a36Sopenharmony_civoid snd_hda_shutup_pins(struct hda_codec *codec); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci/* SPDIF controls */ 40162306a36Sopenharmony_cistruct hda_spdif_out { 40262306a36Sopenharmony_ci hda_nid_t nid; /* Converter nid values relate to */ 40362306a36Sopenharmony_ci unsigned int status; /* IEC958 status bits */ 40462306a36Sopenharmony_ci unsigned short ctls; /* SPDIF control bits */ 40562306a36Sopenharmony_ci}; 40662306a36Sopenharmony_cistruct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, 40762306a36Sopenharmony_ci hda_nid_t nid); 40862306a36Sopenharmony_civoid snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx); 40962306a36Sopenharmony_civoid snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid); 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci/* 41262306a36Sopenharmony_ci * Mixer 41362306a36Sopenharmony_ci */ 41462306a36Sopenharmony_ciint snd_hda_codec_build_controls(struct hda_codec *codec); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci/* 41762306a36Sopenharmony_ci * PCM 41862306a36Sopenharmony_ci */ 41962306a36Sopenharmony_ciint snd_hda_codec_parse_pcms(struct hda_codec *codec); 42062306a36Sopenharmony_ciint snd_hda_codec_build_pcms(struct hda_codec *codec); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci__printf(2, 3) 42362306a36Sopenharmony_cistruct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, 42462306a36Sopenharmony_ci const char *fmt, ...); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_civoid snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci refcount_inc(&pcm->codec->pcm_ref); 43162306a36Sopenharmony_ci} 43262306a36Sopenharmony_civoid snd_hda_codec_pcm_put(struct hda_pcm *pcm); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ciint snd_hda_codec_prepare(struct hda_codec *codec, 43562306a36Sopenharmony_ci struct hda_pcm_stream *hinfo, 43662306a36Sopenharmony_ci unsigned int stream, 43762306a36Sopenharmony_ci unsigned int format, 43862306a36Sopenharmony_ci struct snd_pcm_substream *substream); 43962306a36Sopenharmony_civoid snd_hda_codec_cleanup(struct hda_codec *codec, 44062306a36Sopenharmony_ci struct hda_pcm_stream *hinfo, 44162306a36Sopenharmony_ci struct snd_pcm_substream *substream); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_civoid snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, 44462306a36Sopenharmony_ci u32 stream_tag, 44562306a36Sopenharmony_ci int channel_id, int format); 44662306a36Sopenharmony_civoid __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, 44762306a36Sopenharmony_ci int do_now); 44862306a36Sopenharmony_ci#define snd_hda_codec_cleanup_stream(codec, nid) \ 44962306a36Sopenharmony_ci __snd_hda_codec_cleanup_stream(codec, nid, 0) 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \ 45262306a36Sopenharmony_ci snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp) 45362306a36Sopenharmony_ci#define snd_hda_is_supported_format(codec, nid, fmt) \ 45462306a36Sopenharmony_ci snd_hdac_is_supported_format(&(codec)->core, nid, fmt) 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ciextern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[]; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ciint snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec, 45962306a36Sopenharmony_ci struct hda_pcm *cpcm); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci/* 46262306a36Sopenharmony_ci * Misc 46362306a36Sopenharmony_ci */ 46462306a36Sopenharmony_civoid snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); 46562306a36Sopenharmony_civoid snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, 46662306a36Sopenharmony_ci unsigned int power_state); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ciint snd_hda_lock_devices(struct hda_bus *bus); 46962306a36Sopenharmony_civoid snd_hda_unlock_devices(struct hda_bus *bus); 47062306a36Sopenharmony_civoid snd_hda_bus_reset(struct hda_bus *bus); 47162306a36Sopenharmony_civoid snd_hda_bus_reset_codecs(struct hda_bus *bus); 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ciint snd_hda_codec_set_name(struct hda_codec *codec, const char *name); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci/* 47662306a36Sopenharmony_ci * power management 47762306a36Sopenharmony_ci */ 47862306a36Sopenharmony_ciextern const struct dev_pm_ops hda_codec_driver_pm; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_cistatic inline 48162306a36Sopenharmony_ciint hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci#ifdef CONFIG_PM 48462306a36Sopenharmony_ci if (codec->patch_ops.check_power_status) 48562306a36Sopenharmony_ci return codec->patch_ops.check_power_status(codec, nid); 48662306a36Sopenharmony_ci#endif 48762306a36Sopenharmony_ci return 0; 48862306a36Sopenharmony_ci} 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci/* 49162306a36Sopenharmony_ci * power saving 49262306a36Sopenharmony_ci */ 49362306a36Sopenharmony_ci#define snd_hda_power_up(codec) snd_hdac_power_up(&(codec)->core) 49462306a36Sopenharmony_ci#define snd_hda_power_up_pm(codec) snd_hdac_power_up_pm(&(codec)->core) 49562306a36Sopenharmony_ci#define snd_hda_power_down(codec) snd_hdac_power_down(&(codec)->core) 49662306a36Sopenharmony_ci#define snd_hda_power_down_pm(codec) snd_hdac_power_down_pm(&(codec)->core) 49762306a36Sopenharmony_ci#ifdef CONFIG_PM 49862306a36Sopenharmony_civoid snd_hda_codec_set_power_save(struct hda_codec *codec, int delay); 49962306a36Sopenharmony_civoid snd_hda_set_power_save(struct hda_bus *bus, int delay); 50062306a36Sopenharmony_civoid snd_hda_update_power_acct(struct hda_codec *codec); 50162306a36Sopenharmony_ci#else 50262306a36Sopenharmony_cistatic inline void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay) {} 50362306a36Sopenharmony_cistatic inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {} 50462306a36Sopenharmony_ci#endif 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic inline bool hda_codec_need_resume(struct hda_codec *codec) 50762306a36Sopenharmony_ci{ 50862306a36Sopenharmony_ci return !codec->relaxed_resume && codec->jacktbl.used; 50962306a36Sopenharmony_ci} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci#ifdef CONFIG_SND_HDA_PATCH_LOADER 51262306a36Sopenharmony_ci/* 51362306a36Sopenharmony_ci * patch firmware 51462306a36Sopenharmony_ci */ 51562306a36Sopenharmony_ciint snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf); 51662306a36Sopenharmony_ci#endif 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci#ifdef CONFIG_SND_HDA_DSP_LOADER 51962306a36Sopenharmony_ciint snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format, 52062306a36Sopenharmony_ci unsigned int size, 52162306a36Sopenharmony_ci struct snd_dma_buffer *bufp); 52262306a36Sopenharmony_civoid snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start); 52362306a36Sopenharmony_civoid snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, 52462306a36Sopenharmony_ci struct snd_dma_buffer *dmab); 52562306a36Sopenharmony_ci#else 52662306a36Sopenharmony_cistatic inline int 52762306a36Sopenharmony_cisnd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format, 52862306a36Sopenharmony_ci unsigned int size, 52962306a36Sopenharmony_ci struct snd_dma_buffer *bufp) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci return -ENOSYS; 53262306a36Sopenharmony_ci} 53362306a36Sopenharmony_cistatic inline void 53462306a36Sopenharmony_cisnd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {} 53562306a36Sopenharmony_cistatic inline void 53662306a36Sopenharmony_cisnd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, 53762306a36Sopenharmony_ci struct snd_dma_buffer *dmab) {} 53862306a36Sopenharmony_ci#endif 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci#endif /* __SOUND_HDA_CODEC_H */ 541