11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2be57bfffSPierre-Louis Bossart /*
3be57bfffSPierre-Louis Bossart * Universal Interface for Intel High Definition Audio Codec
4be57bfffSPierre-Louis Bossart *
5be57bfffSPierre-Louis Bossart * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
6be57bfffSPierre-Louis Bossart */
7be57bfffSPierre-Louis Bossart
8be57bfffSPierre-Louis Bossart #ifndef __SOUND_HDA_CODEC_H
9be57bfffSPierre-Louis Bossart #define __SOUND_HDA_CODEC_H
10be57bfffSPierre-Louis Bossart
117206998fSTakashi Iwai #include <linux/refcount.h>
12be57bfffSPierre-Louis Bossart #include <linux/mod_devicetable.h>
13be57bfffSPierre-Louis Bossart #include <sound/info.h>
14be57bfffSPierre-Louis Bossart #include <sound/control.h>
15be57bfffSPierre-Louis Bossart #include <sound/pcm.h>
16be57bfffSPierre-Louis Bossart #include <sound/hwdep.h>
17be57bfffSPierre-Louis Bossart #include <sound/hdaudio.h>
18be57bfffSPierre-Louis Bossart #include <sound/hda_verbs.h>
19be57bfffSPierre-Louis Bossart #include <sound/hda_regmap.h>
20be57bfffSPierre-Louis Bossart
21be57bfffSPierre-Louis Bossart /*
22be57bfffSPierre-Louis Bossart * Structures
23be57bfffSPierre-Louis Bossart */
24be57bfffSPierre-Louis Bossart
25be57bfffSPierre-Louis Bossart struct hda_bus;
26be57bfffSPierre-Louis Bossart struct hda_beep;
27be57bfffSPierre-Louis Bossart struct hda_codec;
28be57bfffSPierre-Louis Bossart struct hda_pcm;
29be57bfffSPierre-Louis Bossart struct hda_pcm_stream;
30be57bfffSPierre-Louis Bossart
31be57bfffSPierre-Louis Bossart /*
32be57bfffSPierre-Louis Bossart * codec bus
33be57bfffSPierre-Louis Bossart *
34be57bfffSPierre-Louis Bossart * each controller needs to creata a hda_bus to assign the accessor.
35be57bfffSPierre-Louis Bossart * A hda_bus contains several codecs in the list codec_list.
36be57bfffSPierre-Louis Bossart */
37be57bfffSPierre-Louis Bossart struct hda_bus {
38be57bfffSPierre-Louis Bossart struct hdac_bus core;
39be57bfffSPierre-Louis Bossart
40be57bfffSPierre-Louis Bossart struct snd_card *card;
41be57bfffSPierre-Louis Bossart
42be57bfffSPierre-Louis Bossart struct pci_dev *pci;
43be57bfffSPierre-Louis Bossart const char *modelname;
44be57bfffSPierre-Louis Bossart
45be57bfffSPierre-Louis Bossart struct mutex prepare_mutex;
46be57bfffSPierre-Louis Bossart
47be57bfffSPierre-Louis Bossart /* assigned PCMs */
48be57bfffSPierre-Louis Bossart DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
49be57bfffSPierre-Louis Bossart
50be57bfffSPierre-Louis Bossart /* misc op flags */
51be57bfffSPierre-Louis Bossart unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
52be57bfffSPierre-Louis Bossart /* status for codec/controller */
53be57bfffSPierre-Louis Bossart unsigned int shutdown :1; /* being unloaded */
54be57bfffSPierre-Louis Bossart unsigned int response_reset:1; /* controller was reset */
55be57bfffSPierre-Louis Bossart unsigned int in_reset:1; /* during reset operation */
56be57bfffSPierre-Louis Bossart unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
57305a0adeSTakashi Iwai unsigned int bus_probing :1; /* during probing process */
58dd23e1d5STakashi Iwai unsigned int keep_power:1; /* keep power up for notification */
59b33115bdSMohan Kumar unsigned int jackpoll_in_suspend:1; /* keep jack polling during
60b33115bdSMohan Kumar * runtime suspend
61b33115bdSMohan Kumar */
62be57bfffSPierre-Louis Bossart
63be57bfffSPierre-Louis Bossart int primary_dig_out_type; /* primary digital out PCM type */
64be57bfffSPierre-Louis Bossart unsigned int mixer_assigned; /* codec addr for mixer name */
65be57bfffSPierre-Louis Bossart };
66be57bfffSPierre-Louis Bossart
67be57bfffSPierre-Louis Bossart /* from hdac_bus to hda_bus */
68be57bfffSPierre-Louis Bossart #define to_hda_bus(bus) container_of(bus, struct hda_bus, core)
69be57bfffSPierre-Louis Bossart
70be57bfffSPierre-Louis Bossart /*
71be57bfffSPierre-Louis Bossart * codec preset
72be57bfffSPierre-Louis Bossart *
73be57bfffSPierre-Louis Bossart * Known codecs have the patch to build and set up the controls/PCMs
74be57bfffSPierre-Louis Bossart * better than the generic parser.
75be57bfffSPierre-Louis Bossart */
76be57bfffSPierre-Louis Bossart typedef int (*hda_codec_patch_t)(struct hda_codec *);
77be57bfffSPierre-Louis Bossart
78be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_SKIP_PROBE 0x00000001
79be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
80be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_GENERIC 0x00000201
81be57bfffSPierre-Louis Bossart
82be57bfffSPierre-Louis Bossart #define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \
83be57bfffSPierre-Louis Bossart { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
84be57bfffSPierre-Louis Bossart .api_version = HDA_DEV_LEGACY, \
85be57bfffSPierre-Louis Bossart .driver_data = (unsigned long)(_patch) }
86be57bfffSPierre-Louis Bossart #define HDA_CODEC_ENTRY(_vid, _name, _patch) \
87be57bfffSPierre-Louis Bossart HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch)
88be57bfffSPierre-Louis Bossart
89be57bfffSPierre-Louis Bossart struct hda_codec_driver {
90be57bfffSPierre-Louis Bossart struct hdac_driver core;
91be57bfffSPierre-Louis Bossart const struct hda_device_id *id;
92be57bfffSPierre-Louis Bossart };
93be57bfffSPierre-Louis Bossart
94be57bfffSPierre-Louis Bossart int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
95be57bfffSPierre-Louis Bossart struct module *owner);
96be57bfffSPierre-Louis Bossart #define hda_codec_driver_register(drv) \
97be57bfffSPierre-Louis Bossart __hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE)
98be57bfffSPierre-Louis Bossart void hda_codec_driver_unregister(struct hda_codec_driver *drv);
99be57bfffSPierre-Louis Bossart #define module_hda_codec_driver(drv) \
100be57bfffSPierre-Louis Bossart module_driver(drv, hda_codec_driver_register, \
101be57bfffSPierre-Louis Bossart hda_codec_driver_unregister)
102be57bfffSPierre-Louis Bossart
103be57bfffSPierre-Louis Bossart /* ops set by the preset patch */
104be57bfffSPierre-Louis Bossart struct hda_codec_ops {
105be57bfffSPierre-Louis Bossart int (*build_controls)(struct hda_codec *codec);
106be57bfffSPierre-Louis Bossart int (*build_pcms)(struct hda_codec *codec);
107be57bfffSPierre-Louis Bossart int (*init)(struct hda_codec *codec);
108be57bfffSPierre-Louis Bossart void (*free)(struct hda_codec *codec);
109be57bfffSPierre-Louis Bossart void (*unsol_event)(struct hda_codec *codec, unsigned int res);
110be57bfffSPierre-Louis Bossart void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
111be57bfffSPierre-Louis Bossart unsigned int power_state);
112be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
113be57bfffSPierre-Louis Bossart int (*suspend)(struct hda_codec *codec);
114be57bfffSPierre-Louis Bossart int (*resume)(struct hda_codec *codec);
115be57bfffSPierre-Louis Bossart int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
116be57bfffSPierre-Louis Bossart #endif
117be57bfffSPierre-Louis Bossart void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
118be57bfffSPierre-Louis Bossart };
119be57bfffSPierre-Louis Bossart
120be57bfffSPierre-Louis Bossart /* PCM callbacks */
121be57bfffSPierre-Louis Bossart struct hda_pcm_ops {
122be57bfffSPierre-Louis Bossart int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
123be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
124be57bfffSPierre-Louis Bossart int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
125be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
126be57bfffSPierre-Louis Bossart int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
127be57bfffSPierre-Louis Bossart unsigned int stream_tag, unsigned int format,
128be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
129be57bfffSPierre-Louis Bossart int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
130be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
131be57bfffSPierre-Louis Bossart unsigned int (*get_delay)(struct hda_pcm_stream *info,
132be57bfffSPierre-Louis Bossart struct hda_codec *codec,
133be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
134be57bfffSPierre-Louis Bossart };
135be57bfffSPierre-Louis Bossart
136be57bfffSPierre-Louis Bossart /* PCM information for each substream */
137be57bfffSPierre-Louis Bossart struct hda_pcm_stream {
138be57bfffSPierre-Louis Bossart unsigned int substreams; /* number of substreams, 0 = not exist*/
139be57bfffSPierre-Louis Bossart unsigned int channels_min; /* min. number of channels */
140be57bfffSPierre-Louis Bossart unsigned int channels_max; /* max. number of channels */
141be57bfffSPierre-Louis Bossart hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
142be57bfffSPierre-Louis Bossart u32 rates; /* supported rates */
143be57bfffSPierre-Louis Bossart u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
144be57bfffSPierre-Louis Bossart unsigned int maxbps; /* supported max. bit per sample */
145be57bfffSPierre-Louis Bossart const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
146be57bfffSPierre-Louis Bossart struct hda_pcm_ops ops;
147be57bfffSPierre-Louis Bossart };
148be57bfffSPierre-Louis Bossart
149be57bfffSPierre-Louis Bossart /* PCM types */
150be57bfffSPierre-Louis Bossart enum {
151be57bfffSPierre-Louis Bossart HDA_PCM_TYPE_AUDIO,
152be57bfffSPierre-Louis Bossart HDA_PCM_TYPE_SPDIF,
153be57bfffSPierre-Louis Bossart HDA_PCM_TYPE_HDMI,
154be57bfffSPierre-Louis Bossart HDA_PCM_TYPE_MODEM,
155be57bfffSPierre-Louis Bossart HDA_PCM_NTYPES
156be57bfffSPierre-Louis Bossart };
157be57bfffSPierre-Louis Bossart
158be57bfffSPierre-Louis Bossart #define SNDRV_PCM_INVALID_DEVICE (-1)
159be57bfffSPierre-Louis Bossart /* for PCM creation */
160be57bfffSPierre-Louis Bossart struct hda_pcm {
161be57bfffSPierre-Louis Bossart char *name;
162be57bfffSPierre-Louis Bossart struct hda_pcm_stream stream[2];
163be57bfffSPierre-Louis Bossart unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
164be57bfffSPierre-Louis Bossart int device; /* device number to assign */
165be57bfffSPierre-Louis Bossart struct snd_pcm *pcm; /* assigned PCM instance */
166be57bfffSPierre-Louis Bossart bool own_chmap; /* codec driver provides own channel maps */
167be57bfffSPierre-Louis Bossart /* private: */
168be57bfffSPierre-Louis Bossart struct hda_codec *codec;
169be57bfffSPierre-Louis Bossart struct list_head list;
1707206998fSTakashi Iwai unsigned int disconnected:1;
171be57bfffSPierre-Louis Bossart };
172be57bfffSPierre-Louis Bossart
173be57bfffSPierre-Louis Bossart /* codec information */
174be57bfffSPierre-Louis Bossart struct hda_codec {
175be57bfffSPierre-Louis Bossart struct hdac_device core;
176be57bfffSPierre-Louis Bossart struct hda_bus *bus;
177be57bfffSPierre-Louis Bossart struct snd_card *card;
178be57bfffSPierre-Louis Bossart unsigned int addr; /* codec addr*/
179be57bfffSPierre-Louis Bossart u32 probe_id; /* overridden id for probing */
180be57bfffSPierre-Louis Bossart
181be57bfffSPierre-Louis Bossart /* detected preset */
182be57bfffSPierre-Louis Bossart const struct hda_device_id *preset;
183be57bfffSPierre-Louis Bossart const char *modelname; /* model name for preset */
184be57bfffSPierre-Louis Bossart
185be57bfffSPierre-Louis Bossart /* set by patch */
186be57bfffSPierre-Louis Bossart struct hda_codec_ops patch_ops;
187be57bfffSPierre-Louis Bossart
188be57bfffSPierre-Louis Bossart /* PCM to create, set by patch_ops.build_pcms callback */
189be57bfffSPierre-Louis Bossart struct list_head pcm_list_head;
1907206998fSTakashi Iwai refcount_t pcm_ref;
1917206998fSTakashi Iwai wait_queue_head_t remove_sleep;
192be57bfffSPierre-Louis Bossart
193be57bfffSPierre-Louis Bossart /* codec specific info */
194be57bfffSPierre-Louis Bossart void *spec;
195be57bfffSPierre-Louis Bossart
196be57bfffSPierre-Louis Bossart /* beep device */
197be57bfffSPierre-Louis Bossart struct hda_beep *beep;
198be57bfffSPierre-Louis Bossart unsigned int beep_mode;
199be57bfffSPierre-Louis Bossart
200be57bfffSPierre-Louis Bossart /* widget capabilities cache */
201be57bfffSPierre-Louis Bossart u32 *wcaps;
202be57bfffSPierre-Louis Bossart
203be57bfffSPierre-Louis Bossart struct snd_array mixers; /* list of assigned mixer elements */
204be57bfffSPierre-Louis Bossart struct snd_array nids; /* list of mapped mixer elements */
205be57bfffSPierre-Louis Bossart
206be57bfffSPierre-Louis Bossart struct list_head conn_list; /* linked-list of connection-list */
207be57bfffSPierre-Louis Bossart
208be57bfffSPierre-Louis Bossart struct mutex spdif_mutex;
209be57bfffSPierre-Louis Bossart struct mutex control_mutex;
210be57bfffSPierre-Louis Bossart struct snd_array spdif_out;
211be57bfffSPierre-Louis Bossart unsigned int spdif_in_enable; /* SPDIF input enable? */
2129ab0cb30STakashi Iwai const hda_nid_t *follower_dig_outs; /* optional digital out follower widgets */
213be57bfffSPierre-Louis Bossart struct snd_array init_pins; /* initial (BIOS) pin configurations */
214be57bfffSPierre-Louis Bossart struct snd_array driver_pins; /* pin configs set by codec parser */
215be57bfffSPierre-Louis Bossart struct snd_array cvt_setups; /* audio convert setups */
216be57bfffSPierre-Louis Bossart
217be57bfffSPierre-Louis Bossart struct mutex user_mutex;
218be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_RECONFIG
219be57bfffSPierre-Louis Bossart struct snd_array init_verbs; /* additional init verbs */
220be57bfffSPierre-Louis Bossart struct snd_array hints; /* additional hints */
221be57bfffSPierre-Louis Bossart struct snd_array user_pins; /* default pin configs to override */
222be57bfffSPierre-Louis Bossart #endif
223be57bfffSPierre-Louis Bossart
224be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_HWDEP
225be57bfffSPierre-Louis Bossart struct snd_hwdep *hwdep; /* assigned hwdep device */
226be57bfffSPierre-Louis Bossart #endif
227be57bfffSPierre-Louis Bossart
228be57bfffSPierre-Louis Bossart /* misc flags */
229c0f1886dSTakashi Iwai unsigned int configured:1; /* codec was configured */
230be57bfffSPierre-Louis Bossart unsigned int in_freeing:1; /* being released */
231029d92c2STakashi Iwai unsigned int display_power_control:1; /* needs display power */
232be57bfffSPierre-Louis Bossart unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
233be57bfffSPierre-Louis Bossart * status change
234be57bfffSPierre-Louis Bossart * (e.g. Realtek codecs)
235be57bfffSPierre-Louis Bossart */
236be57bfffSPierre-Louis Bossart unsigned int pin_amp_workaround:1; /* pin out-amp takes index
237be57bfffSPierre-Louis Bossart * (e.g. Conexant codecs)
238be57bfffSPierre-Louis Bossart */
239be57bfffSPierre-Louis Bossart unsigned int single_adc_amp:1; /* adc in-amp takes no index
240be57bfffSPierre-Louis Bossart * (e.g. CX20549 codec)
241be57bfffSPierre-Louis Bossart */
242be57bfffSPierre-Louis Bossart unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
243be57bfffSPierre-Louis Bossart unsigned int pins_shutup:1; /* pins are shut up */
244be57bfffSPierre-Louis Bossart unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
245be57bfffSPierre-Louis Bossart unsigned int no_jack_detect:1; /* Machine has no jack-detection */
246be57bfffSPierre-Louis Bossart unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */
247be57bfffSPierre-Louis Bossart unsigned int inv_jack_detect:1; /* broken h/w: inverted detection bit */
248be57bfffSPierre-Louis Bossart unsigned int pcm_format_first:1; /* PCM format must be set first */
249be57bfffSPierre-Louis Bossart unsigned int cached_write:1; /* write only to caches */
250be57bfffSPierre-Louis Bossart unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
251be57bfffSPierre-Louis Bossart unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
252be57bfffSPierre-Louis Bossart unsigned int power_save_node:1; /* advanced PM for each widget */
253be57bfffSPierre-Louis Bossart unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
254be57bfffSPierre-Louis Bossart unsigned int force_pin_prefix:1; /* Add location prefix */
255be57bfffSPierre-Louis Bossart unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
2564914da2fSTakashi Iwai unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
257a6e7d0a4SKai Vehmanen unsigned int forced_resume:1; /* forced resume for jack */
258ee0b089dSKai Vehmanen unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
259*d045bcefSJaroslav Kysela unsigned int ctl_dev_id:1; /* old control element id build behaviour */
2604914da2fSTakashi Iwai
261be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
262be57bfffSPierre-Louis Bossart unsigned long power_on_acct;
263be57bfffSPierre-Louis Bossart unsigned long power_off_acct;
264be57bfffSPierre-Louis Bossart unsigned long power_jiffies;
265be57bfffSPierre-Louis Bossart #endif
266be57bfffSPierre-Louis Bossart
267be57bfffSPierre-Louis Bossart /* filter the requested power state per nid */
268be57bfffSPierre-Louis Bossart unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid,
269be57bfffSPierre-Louis Bossart unsigned int power_state);
270be57bfffSPierre-Louis Bossart
271be57bfffSPierre-Louis Bossart /* codec-specific additional proc output */
272be57bfffSPierre-Louis Bossart void (*proc_widget_hook)(struct snd_info_buffer *buffer,
273be57bfffSPierre-Louis Bossart struct hda_codec *codec, hda_nid_t nid);
274be57bfffSPierre-Louis Bossart
275be57bfffSPierre-Louis Bossart /* jack detection */
276be57bfffSPierre-Louis Bossart struct snd_array jacktbl;
277be57bfffSPierre-Louis Bossart unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
278be57bfffSPierre-Louis Bossart struct delayed_work jackpoll_work;
279be57bfffSPierre-Louis Bossart
280be57bfffSPierre-Louis Bossart int depop_delay; /* depop delay in ms, -1 for default delay time */
281be57bfffSPierre-Louis Bossart
282be57bfffSPierre-Louis Bossart /* fix-up list */
283be57bfffSPierre-Louis Bossart int fixup_id;
284be57bfffSPierre-Louis Bossart const struct hda_fixup *fixup_list;
285be57bfffSPierre-Louis Bossart const char *fixup_name;
286be57bfffSPierre-Louis Bossart
287be57bfffSPierre-Louis Bossart /* additional init verbs */
288be57bfffSPierre-Louis Bossart struct snd_array verbs;
289be57bfffSPierre-Louis Bossart };
290be57bfffSPierre-Louis Bossart
291be57bfffSPierre-Louis Bossart #define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, core.dev)
292be57bfffSPierre-Louis Bossart #define hda_codec_dev(_dev) (&(_dev)->core.dev)
293be57bfffSPierre-Louis Bossart
2948c11827bSKai-Heng Feng #define hdac_to_hda_codec(_hdac) container_of(_hdac, struct hda_codec, core)
2958c11827bSKai-Heng Feng
296be57bfffSPierre-Louis Bossart #define list_for_each_codec(c, bus) \
297be57bfffSPierre-Louis Bossart list_for_each_entry(c, &(bus)->core.codec_list, core.list)
298be57bfffSPierre-Louis Bossart #define list_for_each_codec_safe(c, n, bus) \
299be57bfffSPierre-Louis Bossart list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
300be57bfffSPierre-Louis Bossart
301be57bfffSPierre-Louis Bossart /* snd_hda_codec_read/write optional flags */
302be57bfffSPierre-Louis Bossart #define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0)
303be57bfffSPierre-Louis Bossart
304be57bfffSPierre-Louis Bossart /*
305be57bfffSPierre-Louis Bossart * constructors
306be57bfffSPierre-Louis Bossart */
307595511a3SCezary Rojewski __printf(3, 4) struct hda_codec *
308595511a3SCezary Rojewski snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
309595511a3SCezary Rojewski const char *fmt, ...);
310be57bfffSPierre-Louis Bossart int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
311be57bfffSPierre-Louis Bossart unsigned int codec_addr, struct hda_codec **codecp);
312be57bfffSPierre-Louis Bossart int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
31317e0c4cbSCezary Rojewski unsigned int codec_addr, struct hda_codec *codec,
31417e0c4cbSCezary Rojewski bool snddev_managed);
315be57bfffSPierre-Louis Bossart int snd_hda_codec_configure(struct hda_codec *codec);
316be57bfffSPierre-Louis Bossart int snd_hda_codec_update_widgets(struct hda_codec *codec);
31717e0c4cbSCezary Rojewski void snd_hda_codec_register(struct hda_codec *codec);
31817e0c4cbSCezary Rojewski void snd_hda_codec_unregister(struct hda_codec *codec);
319bb682f7aSCezary Rojewski void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
320be57bfffSPierre-Louis Bossart
321be57bfffSPierre-Louis Bossart /*
322be57bfffSPierre-Louis Bossart * low level functions
323be57bfffSPierre-Louis Bossart */
324be57bfffSPierre-Louis Bossart static inline unsigned int
snd_hda_codec_read(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)325be57bfffSPierre-Louis Bossart snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
326be57bfffSPierre-Louis Bossart int flags,
327be57bfffSPierre-Louis Bossart unsigned int verb, unsigned int parm)
328be57bfffSPierre-Louis Bossart {
329be57bfffSPierre-Louis Bossart return snd_hdac_codec_read(&codec->core, nid, flags, verb, parm);
330be57bfffSPierre-Louis Bossart }
331be57bfffSPierre-Louis Bossart
332be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_write(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)333be57bfffSPierre-Louis Bossart snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
334be57bfffSPierre-Louis Bossart unsigned int verb, unsigned int parm)
335be57bfffSPierre-Louis Bossart {
336be57bfffSPierre-Louis Bossart return snd_hdac_codec_write(&codec->core, nid, flags, verb, parm);
337be57bfffSPierre-Louis Bossart }
338be57bfffSPierre-Louis Bossart
339be57bfffSPierre-Louis Bossart #define snd_hda_param_read(codec, nid, param) \
340be57bfffSPierre-Louis Bossart snd_hdac_read_parm(&(codec)->core, nid, param)
341be57bfffSPierre-Louis Bossart #define snd_hda_get_sub_nodes(codec, nid, start_nid) \
342be57bfffSPierre-Louis Bossart snd_hdac_get_sub_nodes(&(codec)->core, nid, start_nid)
343be57bfffSPierre-Louis Bossart int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
344be57bfffSPierre-Louis Bossart hda_nid_t *conn_list, int max_conns);
345be57bfffSPierre-Louis Bossart static inline int
snd_hda_get_num_conns(struct hda_codec * codec,hda_nid_t nid)346be57bfffSPierre-Louis Bossart snd_hda_get_num_conns(struct hda_codec *codec, hda_nid_t nid)
347be57bfffSPierre-Louis Bossart {
348be57bfffSPierre-Louis Bossart return snd_hda_get_connections(codec, nid, NULL, 0);
349be57bfffSPierre-Louis Bossart }
350be57bfffSPierre-Louis Bossart
351be57bfffSPierre-Louis Bossart #define snd_hda_get_raw_connections(codec, nid, list, max_conns) \
352be57bfffSPierre-Louis Bossart snd_hdac_get_connections(&(codec)->core, nid, list, max_conns)
353be57bfffSPierre-Louis Bossart #define snd_hda_get_num_raw_conns(codec, nid) \
3540183a855STom Rix snd_hdac_get_connections(&(codec)->core, nid, NULL, 0)
355be57bfffSPierre-Louis Bossart
356be57bfffSPierre-Louis Bossart int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
357be57bfffSPierre-Louis Bossart const hda_nid_t **listp);
358be57bfffSPierre-Louis Bossart int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
359be57bfffSPierre-Louis Bossart const hda_nid_t *list);
360be57bfffSPierre-Louis Bossart int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
361be57bfffSPierre-Louis Bossart hda_nid_t nid, int recursive);
362be57bfffSPierre-Louis Bossart unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid);
363be57bfffSPierre-Louis Bossart int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
364be57bfffSPierre-Louis Bossart u8 *dev_list, int max_devices);
365be57bfffSPierre-Louis Bossart int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid);
366be57bfffSPierre-Louis Bossart int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id);
367be57bfffSPierre-Louis Bossart
368be57bfffSPierre-Louis Bossart struct hda_verb {
369be57bfffSPierre-Louis Bossart hda_nid_t nid;
370be57bfffSPierre-Louis Bossart u32 verb;
371be57bfffSPierre-Louis Bossart u32 param;
372be57bfffSPierre-Louis Bossart };
373be57bfffSPierre-Louis Bossart
374be57bfffSPierre-Louis Bossart void snd_hda_sequence_write(struct hda_codec *codec,
375be57bfffSPierre-Louis Bossart const struct hda_verb *seq);
376be57bfffSPierre-Louis Bossart
377be57bfffSPierre-Louis Bossart /* cached write */
378be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_write_cache(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)379be57bfffSPierre-Louis Bossart snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
380be57bfffSPierre-Louis Bossart int flags, unsigned int verb, unsigned int parm)
381be57bfffSPierre-Louis Bossart {
382be57bfffSPierre-Louis Bossart return snd_hdac_regmap_write(&codec->core, nid, verb, parm);
383be57bfffSPierre-Louis Bossart }
384be57bfffSPierre-Louis Bossart
385be57bfffSPierre-Louis Bossart /* the struct for codec->pin_configs */
386be57bfffSPierre-Louis Bossart struct hda_pincfg {
387be57bfffSPierre-Louis Bossart hda_nid_t nid;
388be57bfffSPierre-Louis Bossart unsigned char ctrl; /* original pin control value */
389be57bfffSPierre-Louis Bossart unsigned char target; /* target pin control value */
390be57bfffSPierre-Louis Bossart unsigned int cfg; /* default configuration */
391be57bfffSPierre-Louis Bossart };
392be57bfffSPierre-Louis Bossart
393be57bfffSPierre-Louis Bossart unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid);
394be57bfffSPierre-Louis Bossart int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
395be57bfffSPierre-Louis Bossart unsigned int cfg);
396be57bfffSPierre-Louis Bossart int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
397be57bfffSPierre-Louis Bossart hda_nid_t nid, unsigned int cfg); /* for hwdep */
398be57bfffSPierre-Louis Bossart void snd_hda_shutup_pins(struct hda_codec *codec);
399be57bfffSPierre-Louis Bossart
400be57bfffSPierre-Louis Bossart /* SPDIF controls */
401be57bfffSPierre-Louis Bossart struct hda_spdif_out {
402be57bfffSPierre-Louis Bossart hda_nid_t nid; /* Converter nid values relate to */
403be57bfffSPierre-Louis Bossart unsigned int status; /* IEC958 status bits */
404be57bfffSPierre-Louis Bossart unsigned short ctls; /* SPDIF control bits */
405be57bfffSPierre-Louis Bossart };
406be57bfffSPierre-Louis Bossart struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
407be57bfffSPierre-Louis Bossart hda_nid_t nid);
408be57bfffSPierre-Louis Bossart void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
409be57bfffSPierre-Louis Bossart void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
410be57bfffSPierre-Louis Bossart
411be57bfffSPierre-Louis Bossart /*
412be57bfffSPierre-Louis Bossart * Mixer
413be57bfffSPierre-Louis Bossart */
414be57bfffSPierre-Louis Bossart int snd_hda_codec_build_controls(struct hda_codec *codec);
415be57bfffSPierre-Louis Bossart
416be57bfffSPierre-Louis Bossart /*
417be57bfffSPierre-Louis Bossart * PCM
418be57bfffSPierre-Louis Bossart */
419be57bfffSPierre-Louis Bossart int snd_hda_codec_parse_pcms(struct hda_codec *codec);
420be57bfffSPierre-Louis Bossart int snd_hda_codec_build_pcms(struct hda_codec *codec);
421be57bfffSPierre-Louis Bossart
422be57bfffSPierre-Louis Bossart __printf(2, 3)
423be57bfffSPierre-Louis Bossart struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
424be57bfffSPierre-Louis Bossart const char *fmt, ...);
425be57bfffSPierre-Louis Bossart
426cc1d0cd8SKai Vehmanen void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
427cc1d0cd8SKai Vehmanen
snd_hda_codec_pcm_get(struct hda_pcm * pcm)428be57bfffSPierre-Louis Bossart static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm)
429be57bfffSPierre-Louis Bossart {
4307206998fSTakashi Iwai refcount_inc(&pcm->codec->pcm_ref);
431be57bfffSPierre-Louis Bossart }
432be57bfffSPierre-Louis Bossart void snd_hda_codec_pcm_put(struct hda_pcm *pcm);
433be57bfffSPierre-Louis Bossart
434be57bfffSPierre-Louis Bossart int snd_hda_codec_prepare(struct hda_codec *codec,
435be57bfffSPierre-Louis Bossart struct hda_pcm_stream *hinfo,
436be57bfffSPierre-Louis Bossart unsigned int stream,
437be57bfffSPierre-Louis Bossart unsigned int format,
438be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
439be57bfffSPierre-Louis Bossart void snd_hda_codec_cleanup(struct hda_codec *codec,
440be57bfffSPierre-Louis Bossart struct hda_pcm_stream *hinfo,
441be57bfffSPierre-Louis Bossart struct snd_pcm_substream *substream);
442be57bfffSPierre-Louis Bossart
443be57bfffSPierre-Louis Bossart void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
444be57bfffSPierre-Louis Bossart u32 stream_tag,
445be57bfffSPierre-Louis Bossart int channel_id, int format);
446be57bfffSPierre-Louis Bossart void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
447be57bfffSPierre-Louis Bossart int do_now);
448be57bfffSPierre-Louis Bossart #define snd_hda_codec_cleanup_stream(codec, nid) \
449be57bfffSPierre-Louis Bossart __snd_hda_codec_cleanup_stream(codec, nid, 0)
450be57bfffSPierre-Louis Bossart
451be57bfffSPierre-Louis Bossart #define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
452be57bfffSPierre-Louis Bossart snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
453be57bfffSPierre-Louis Bossart #define snd_hda_is_supported_format(codec, nid, fmt) \
454be57bfffSPierre-Louis Bossart snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
455be57bfffSPierre-Louis Bossart
456be57bfffSPierre-Louis Bossart extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
457be57bfffSPierre-Louis Bossart
458be57bfffSPierre-Louis Bossart int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
459be57bfffSPierre-Louis Bossart struct hda_pcm *cpcm);
460be57bfffSPierre-Louis Bossart
461be57bfffSPierre-Louis Bossart /*
462be57bfffSPierre-Louis Bossart * Misc
463be57bfffSPierre-Louis Bossart */
464be57bfffSPierre-Louis Bossart void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
465be57bfffSPierre-Louis Bossart void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
466be57bfffSPierre-Louis Bossart unsigned int power_state);
467be57bfffSPierre-Louis Bossart
468be57bfffSPierre-Louis Bossart int snd_hda_lock_devices(struct hda_bus *bus);
469be57bfffSPierre-Louis Bossart void snd_hda_unlock_devices(struct hda_bus *bus);
470be57bfffSPierre-Louis Bossart void snd_hda_bus_reset(struct hda_bus *bus);
471be57bfffSPierre-Louis Bossart void snd_hda_bus_reset_codecs(struct hda_bus *bus);
472be57bfffSPierre-Louis Bossart
473be57bfffSPierre-Louis Bossart int snd_hda_codec_set_name(struct hda_codec *codec, const char *name);
474be57bfffSPierre-Louis Bossart
475be57bfffSPierre-Louis Bossart /*
476be57bfffSPierre-Louis Bossart * power management
477be57bfffSPierre-Louis Bossart */
478be57bfffSPierre-Louis Bossart extern const struct dev_pm_ops hda_codec_driver_pm;
479be57bfffSPierre-Louis Bossart
480be57bfffSPierre-Louis Bossart static inline
hda_call_check_power_status(struct hda_codec * codec,hda_nid_t nid)481be57bfffSPierre-Louis Bossart int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
482be57bfffSPierre-Louis Bossart {
483be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
484be57bfffSPierre-Louis Bossart if (codec->patch_ops.check_power_status)
485be57bfffSPierre-Louis Bossart return codec->patch_ops.check_power_status(codec, nid);
486be57bfffSPierre-Louis Bossart #endif
487be57bfffSPierre-Louis Bossart return 0;
488be57bfffSPierre-Louis Bossart }
489be57bfffSPierre-Louis Bossart
490be57bfffSPierre-Louis Bossart /*
491be57bfffSPierre-Louis Bossart * power saving
492be57bfffSPierre-Louis Bossart */
493be57bfffSPierre-Louis Bossart #define snd_hda_power_up(codec) snd_hdac_power_up(&(codec)->core)
494be57bfffSPierre-Louis Bossart #define snd_hda_power_up_pm(codec) snd_hdac_power_up_pm(&(codec)->core)
495be57bfffSPierre-Louis Bossart #define snd_hda_power_down(codec) snd_hdac_power_down(&(codec)->core)
496be57bfffSPierre-Louis Bossart #define snd_hda_power_down_pm(codec) snd_hdac_power_down_pm(&(codec)->core)
497be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
498bb682f7aSCezary Rojewski void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay);
499be57bfffSPierre-Louis Bossart void snd_hda_set_power_save(struct hda_bus *bus, int delay);
500be57bfffSPierre-Louis Bossart void snd_hda_update_power_acct(struct hda_codec *codec);
501be57bfffSPierre-Louis Bossart #else
snd_hda_codec_set_power_save(struct hda_codec * codec,int delay)502bb682f7aSCezary Rojewski static inline void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay) {}
snd_hda_set_power_save(struct hda_bus * bus,int delay)503be57bfffSPierre-Louis Bossart static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
504be57bfffSPierre-Louis Bossart #endif
505be57bfffSPierre-Louis Bossart
hda_codec_need_resume(struct hda_codec * codec)506c4c8dd6eSTakashi Iwai static inline bool hda_codec_need_resume(struct hda_codec *codec)
507c4c8dd6eSTakashi Iwai {
508c4c8dd6eSTakashi Iwai return !codec->relaxed_resume && codec->jacktbl.used;
509c4c8dd6eSTakashi Iwai }
510c4c8dd6eSTakashi Iwai
511be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_PATCH_LOADER
512be57bfffSPierre-Louis Bossart /*
513be57bfffSPierre-Louis Bossart * patch firmware
514be57bfffSPierre-Louis Bossart */
515be57bfffSPierre-Louis Bossart int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
516be57bfffSPierre-Louis Bossart #endif
517be57bfffSPierre-Louis Bossart
518be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_DSP_LOADER
519be57bfffSPierre-Louis Bossart int snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
520be57bfffSPierre-Louis Bossart unsigned int size,
521be57bfffSPierre-Louis Bossart struct snd_dma_buffer *bufp);
522be57bfffSPierre-Louis Bossart void snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start);
523be57bfffSPierre-Louis Bossart void snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
524be57bfffSPierre-Louis Bossart struct snd_dma_buffer *dmab);
525be57bfffSPierre-Louis Bossart #else
526be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_load_dsp_prepare(struct hda_codec * codec,unsigned int format,unsigned int size,struct snd_dma_buffer * bufp)527be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
528be57bfffSPierre-Louis Bossart unsigned int size,
529be57bfffSPierre-Louis Bossart struct snd_dma_buffer *bufp)
530be57bfffSPierre-Louis Bossart {
531be57bfffSPierre-Louis Bossart return -ENOSYS;
532be57bfffSPierre-Louis Bossart }
533be57bfffSPierre-Louis Bossart static inline void
snd_hda_codec_load_dsp_trigger(struct hda_codec * codec,bool start)534be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {}
535be57bfffSPierre-Louis Bossart static inline void
snd_hda_codec_load_dsp_cleanup(struct hda_codec * codec,struct snd_dma_buffer * dmab)536be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
537be57bfffSPierre-Louis Bossart struct snd_dma_buffer *dmab) {}
538be57bfffSPierre-Louis Bossart #endif
539be57bfffSPierre-Louis Bossart
540be57bfffSPierre-Louis Bossart #endif /* __SOUND_HDA_CODEC_H */
541