xref: /freebsd/sys/dev/sound/pci/hda/hdaa.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1718cf2ccSPedro F. Giffuni /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
47c6b05d2SAlexander Motin  * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca>
57c6b05d2SAlexander Motin  * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org>
67c6b05d2SAlexander Motin  * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org>
77c6b05d2SAlexander Motin  * All rights reserved.
87c6b05d2SAlexander Motin  *
97c6b05d2SAlexander Motin  * Redistribution and use in source and binary forms, with or without
107c6b05d2SAlexander Motin  * modification, are permitted provided that the following conditions
117c6b05d2SAlexander Motin  * are met:
127c6b05d2SAlexander Motin  * 1. Redistributions of source code must retain the above copyright
137c6b05d2SAlexander Motin  *    notice, this list of conditions and the following disclaimer.
147c6b05d2SAlexander Motin  * 2. Redistributions in binary form must reproduce the above copyright
157c6b05d2SAlexander Motin  *    notice, this list of conditions and the following disclaimer in the
167c6b05d2SAlexander Motin  *    documentation and/or other materials provided with the distribution.
177c6b05d2SAlexander Motin  *
187c6b05d2SAlexander Motin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
197c6b05d2SAlexander Motin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
207c6b05d2SAlexander Motin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
217c6b05d2SAlexander Motin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
227c6b05d2SAlexander Motin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
237c6b05d2SAlexander Motin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
247c6b05d2SAlexander Motin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
257c6b05d2SAlexander Motin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
267c6b05d2SAlexander Motin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
277c6b05d2SAlexander Motin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
287c6b05d2SAlexander Motin  * SUCH DAMAGE.
297c6b05d2SAlexander Motin  */
307c6b05d2SAlexander Motin 
317c6b05d2SAlexander Motin /*
327c6b05d2SAlexander Motin  * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
337c6b05d2SAlexander Motin  */
347c6b05d2SAlexander Motin 
357c6b05d2SAlexander Motin #ifndef _HDAA_QUIRKS_H_
367c6b05d2SAlexander Motin #define _HDAA_QUIRKS_H_
377c6b05d2SAlexander Motin 
387c6b05d2SAlexander Motin #define HDAA_GPIO_SHIFT(n)	(n * 3)
397c6b05d2SAlexander Motin #define HDAA_GPIO_MASK(n)	(0x7 << (n * 3))
407c6b05d2SAlexander Motin #define HDAA_GPIO_KEEP(n)	(0x0 << (n * 3))
417c6b05d2SAlexander Motin #define HDAA_GPIO_SET(n)	(0x1 << (n * 3))
427c6b05d2SAlexander Motin #define HDAA_GPIO_CLEAR(n)	(0x2 << (n * 3))
437c6b05d2SAlexander Motin #define HDAA_GPIO_DISABLE(n)	(0x3 << (n * 3))
447c6b05d2SAlexander Motin #define HDAA_GPIO_INPUT(n)	(0x4 << (n * 3))
457c6b05d2SAlexander Motin 
467c6b05d2SAlexander Motin /* 9 - 25 = anything else */
477c6b05d2SAlexander Motin #define HDAA_QUIRK_SOFTPCMVOL	(1 << 9)
487c6b05d2SAlexander Motin #define HDAA_QUIRK_FIXEDRATE	(1 << 10)
497c6b05d2SAlexander Motin #define HDAA_QUIRK_FORCESTEREO	(1 << 11)
507c6b05d2SAlexander Motin #define HDAA_QUIRK_EAPDINV	(1 << 12)
517c6b05d2SAlexander Motin #define HDAA_QUIRK_SENSEINV	(1 << 14)
527c6b05d2SAlexander Motin 
537c6b05d2SAlexander Motin /* 26 - 31 = vrefs */
547c6b05d2SAlexander Motin #define HDAA_QUIRK_IVREF50	(1 << 26)
557c6b05d2SAlexander Motin #define HDAA_QUIRK_IVREF80	(1 << 27)
567c6b05d2SAlexander Motin #define HDAA_QUIRK_IVREF100	(1 << 28)
577c6b05d2SAlexander Motin #define HDAA_QUIRK_OVREF50	(1 << 29)
587c6b05d2SAlexander Motin #define HDAA_QUIRK_OVREF80	(1 << 30)
597a22215cSEitan Adler #define HDAA_QUIRK_OVREF100	(1U << 31)
607c6b05d2SAlexander Motin 
617c6b05d2SAlexander Motin #define HDAA_QUIRK_IVREF	(HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF80 | \
627c6b05d2SAlexander Motin 						HDAA_QUIRK_IVREF100)
637c6b05d2SAlexander Motin #define HDAA_QUIRK_OVREF	(HDAA_QUIRK_OVREF50 | HDAA_QUIRK_OVREF80 | \
647c6b05d2SAlexander Motin 						HDAA_QUIRK_OVREF100)
657c6b05d2SAlexander Motin #define HDAA_QUIRK_VREF		(HDAA_QUIRK_IVREF | HDAA_QUIRK_OVREF)
667c6b05d2SAlexander Motin 
677c6b05d2SAlexander Motin #define HDAA_AMP_VOL_DEFAULT	(-1)
687c6b05d2SAlexander Motin #define HDAA_AMP_MUTE_DEFAULT	(0xffffffff)
697c6b05d2SAlexander Motin #define HDAA_AMP_MUTE_NONE	(0)
707c6b05d2SAlexander Motin #define HDAA_AMP_MUTE_LEFT	(1 << 0)
717c6b05d2SAlexander Motin #define HDAA_AMP_MUTE_RIGHT	(1 << 1)
727c6b05d2SAlexander Motin #define HDAA_AMP_MUTE_ALL	(HDAA_AMP_MUTE_LEFT | HDAA_AMP_MUTE_RIGHT)
737c6b05d2SAlexander Motin 
747c6b05d2SAlexander Motin #define HDAA_AMP_LEFT_MUTED(v)	((v) & (HDAA_AMP_MUTE_LEFT))
757c6b05d2SAlexander Motin #define HDAA_AMP_RIGHT_MUTED(v)	(((v) & HDAA_AMP_MUTE_RIGHT) >> 1)
767c6b05d2SAlexander Motin 
773d741b14SAlexander Motin /* Widget in playback receiving signal from recording. */
787c6b05d2SAlexander Motin #define HDAA_ADC_MONITOR		(1 << 0)
793d741b14SAlexander Motin /* Input mixer widget needs volume control as destination. */
803d741b14SAlexander Motin #define HDAA_IMIX_AS_DST		(2 << 0)
817c6b05d2SAlexander Motin 
827c6b05d2SAlexander Motin #define HDAA_CTL_OUT		1
837c6b05d2SAlexander Motin #define HDAA_CTL_IN		2
847c6b05d2SAlexander Motin 
857c6b05d2SAlexander Motin #define HDA_MAX_CONNS	32
867c6b05d2SAlexander Motin #define HDA_MAX_NAMELEN	32
877c6b05d2SAlexander Motin 
883d741b14SAlexander Motin struct hdaa_audio_as;
893d741b14SAlexander Motin struct hdaa_audio_ctl;
903d741b14SAlexander Motin struct hdaa_chan;
913d741b14SAlexander Motin struct hdaa_devinfo;
923d741b14SAlexander Motin struct hdaa_pcm_devinfo;
933d741b14SAlexander Motin struct hdaa_widget;
943d741b14SAlexander Motin 
957c6b05d2SAlexander Motin struct hdaa_widget {
967c6b05d2SAlexander Motin 	nid_t nid;
977c6b05d2SAlexander Motin 	int type;
987c6b05d2SAlexander Motin 	int enable;
997c6b05d2SAlexander Motin 	int nconns, selconn;
1007c6b05d2SAlexander Motin 	int waspin;
1017c6b05d2SAlexander Motin 	uint32_t pflags;
1027c6b05d2SAlexander Motin 	int bindas;
1037c6b05d2SAlexander Motin 	int bindseqmask;
1047c6b05d2SAlexander Motin 	int ossdev;
1057c6b05d2SAlexander Motin 	uint32_t ossmask;
10688addcbeSAlexander Motin 	int unsol;
1077c6b05d2SAlexander Motin 	nid_t conns[HDA_MAX_CONNS];
1087c6b05d2SAlexander Motin 	u_char connsenable[HDA_MAX_CONNS];
1097c6b05d2SAlexander Motin 	char name[HDA_MAX_NAMELEN];
11088addcbeSAlexander Motin 	uint8_t	*eld;
11188addcbeSAlexander Motin 	int	eld_len;
1127c6b05d2SAlexander Motin 	struct hdaa_devinfo *devinfo;
1137c6b05d2SAlexander Motin 	struct {
1147c6b05d2SAlexander Motin 		uint32_t widget_cap;
1157c6b05d2SAlexander Motin 		uint32_t outamp_cap;
1167c6b05d2SAlexander Motin 		uint32_t inamp_cap;
1177c6b05d2SAlexander Motin 		uint32_t supp_stream_formats;
1187c6b05d2SAlexander Motin 		uint32_t supp_pcm_size_rate;
1197c6b05d2SAlexander Motin 		uint32_t eapdbtl;
1207c6b05d2SAlexander Motin 	} param;
1217c6b05d2SAlexander Motin 	union {
1227c6b05d2SAlexander Motin 		struct {
1237c6b05d2SAlexander Motin 			uint32_t config;
1247c6b05d2SAlexander Motin 			uint32_t original;
1257c6b05d2SAlexander Motin 			uint32_t newconf;
1267c6b05d2SAlexander Motin 			uint32_t cap;
1277c6b05d2SAlexander Motin 			uint32_t ctrl;
128d9360bbfSAlexander Motin 			int	connected;
1297c6b05d2SAlexander Motin 		} pin;
1306fa8e691SAlexander Motin 		struct {
1316fa8e691SAlexander Motin 			uint8_t	stripecap;
1326fa8e691SAlexander Motin 		} conv;
1337c6b05d2SAlexander Motin 	} wclass;
1347c6b05d2SAlexander Motin };
1357c6b05d2SAlexander Motin 
1367c6b05d2SAlexander Motin struct hdaa_audio_ctl {
1377c6b05d2SAlexander Motin 	struct hdaa_widget *widget, *childwidget;
1387c6b05d2SAlexander Motin 	int enable;
1397c6b05d2SAlexander Motin 	int index, dir, ndir;
1407c6b05d2SAlexander Motin 	int mute, step, size, offset;
1417c6b05d2SAlexander Motin 	int left, right, forcemute;
1427c6b05d2SAlexander Motin 	uint32_t muted;
1433d741b14SAlexander Motin 	uint32_t ossmask;	/* OSS devices that may affect control. */
1443d741b14SAlexander Motin 	int	devleft[SOUND_MIXER_NRDEVICES]; /* Left ampl in 1/4dB. */
1453d741b14SAlexander Motin 	int	devright[SOUND_MIXER_NRDEVICES]; /* Right ampl in 1/4dB. */
1463d741b14SAlexander Motin 	int	devmute[SOUND_MIXER_NRDEVICES]; /* Mutes per OSS device. */
1477c6b05d2SAlexander Motin };
1487c6b05d2SAlexander Motin 
1497c6b05d2SAlexander Motin /* Association is a group of pins bound for some special function. */
1507c6b05d2SAlexander Motin struct hdaa_audio_as {
1517c6b05d2SAlexander Motin 	u_char enable;
1527c6b05d2SAlexander Motin 	u_char index;
1537c6b05d2SAlexander Motin 	u_char dir;
1547c6b05d2SAlexander Motin 	u_char pincnt;
1557c6b05d2SAlexander Motin 	u_char fakeredir;
1567c6b05d2SAlexander Motin 	u_char digital;
1577c6b05d2SAlexander Motin 	uint16_t pinset;
1587c6b05d2SAlexander Motin 	nid_t hpredir;
1597c6b05d2SAlexander Motin 	nid_t pins[16];
1607c6b05d2SAlexander Motin 	nid_t dacs[2][16];
1617c6b05d2SAlexander Motin 	int num_chans;
1627c6b05d2SAlexander Motin 	int chans[2];
1637c6b05d2SAlexander Motin 	int location;	/* Pins location, if all have the same */
1647c6b05d2SAlexander Motin 	int mixed;	/* Mixed/multiplexed recording, not multichannel. */
1653d741b14SAlexander Motin 	struct hdaa_pcm_devinfo *pdevinfo;
1667c6b05d2SAlexander Motin };
1677c6b05d2SAlexander Motin 
1687c6b05d2SAlexander Motin struct hdaa_pcm_devinfo {
1697c6b05d2SAlexander Motin 	device_t dev;
1707c6b05d2SAlexander Motin 	struct hdaa_devinfo *devinfo;
1713d741b14SAlexander Motin 	struct	snd_mixer *mixer;
1727c6b05d2SAlexander Motin 	int	index;
1737c6b05d2SAlexander Motin 	int	registered;
1747c6b05d2SAlexander Motin 	int	playas, recas;
1757c6b05d2SAlexander Motin 	u_char	left[SOUND_MIXER_NRDEVICES];
1767c6b05d2SAlexander Motin 	u_char	right[SOUND_MIXER_NRDEVICES];
1773d741b14SAlexander Motin 	int	minamp[SOUND_MIXER_NRDEVICES]; /* Minimal amps in 1/4dB. */
1783d741b14SAlexander Motin 	int	maxamp[SOUND_MIXER_NRDEVICES]; /* Maximal amps in 1/4dB. */
1797c6b05d2SAlexander Motin 	int	chan_size;
1807c6b05d2SAlexander Motin 	int	chan_blkcnt;
1817c6b05d2SAlexander Motin 	u_char	digital;
1823d741b14SAlexander Motin 	uint32_t	ossmask;	/* Mask of supported OSS devices. */
1833d741b14SAlexander Motin 	uint32_t	recsrc;		/* Mask of supported OSS sources. */
184d9360bbfSAlexander Motin 	int		autorecsrc;
1857c6b05d2SAlexander Motin };
1867c6b05d2SAlexander Motin 
1877c6b05d2SAlexander Motin struct hdaa_devinfo {
1887c6b05d2SAlexander Motin 	device_t		dev;
1897c6b05d2SAlexander Motin 	struct mtx		*lock;
1907c6b05d2SAlexander Motin 	nid_t			nid;
1917c6b05d2SAlexander Motin 	nid_t			startnode, endnode;
1927c6b05d2SAlexander Motin 	uint32_t		outamp_cap;
1937c6b05d2SAlexander Motin 	uint32_t		inamp_cap;
1947c6b05d2SAlexander Motin 	uint32_t		supp_stream_formats;
1957c6b05d2SAlexander Motin 	uint32_t		supp_pcm_size_rate;
1967c6b05d2SAlexander Motin 	uint32_t		gpio_cap;
1977c6b05d2SAlexander Motin 	uint32_t		quirks;
1987c6b05d2SAlexander Motin 	uint32_t		newquirks;
1997c6b05d2SAlexander Motin 	uint32_t		gpio;
2007c6b05d2SAlexander Motin 	uint32_t		newgpio;
2017c6b05d2SAlexander Motin 	uint32_t		gpo;
2027c6b05d2SAlexander Motin 	uint32_t		newgpo;
2037c6b05d2SAlexander Motin 	int			nodecnt;
2047c6b05d2SAlexander Motin 	int			ctlcnt;
2057c6b05d2SAlexander Motin 	int			ascnt;
2067c6b05d2SAlexander Motin 	int			num_devs;
2077c6b05d2SAlexander Motin 	int			num_chans;
2087c6b05d2SAlexander Motin 	struct hdaa_widget	*widget;
2097c6b05d2SAlexander Motin 	struct hdaa_audio_ctl	*ctl;
2107c6b05d2SAlexander Motin 	struct hdaa_audio_as	*as;
2117c6b05d2SAlexander Motin 	struct hdaa_pcm_devinfo	*devs;
2127c6b05d2SAlexander Motin 	struct hdaa_chan	*chans;
2137c6b05d2SAlexander Motin 	struct callout		poll_jack;
2147c6b05d2SAlexander Motin 	int			poll_ival;
215fceeeec7SSean Bruno 	uint32_t		init_clear;
2167c6b05d2SAlexander Motin };
2177c6b05d2SAlexander Motin 
2187c6b05d2SAlexander Motin #define HDAA_CHN_RUNNING	0x00000001
2197c6b05d2SAlexander Motin #define HDAA_CHN_SUSPEND	0x00000002
2207c6b05d2SAlexander Motin 
2217c6b05d2SAlexander Motin struct hdaa_chan {
2227c6b05d2SAlexander Motin 	struct snd_dbuf *b;
2237c6b05d2SAlexander Motin 	struct pcm_channel *c;
2247c6b05d2SAlexander Motin 	struct pcmchan_caps caps;
2257c6b05d2SAlexander Motin 	struct hdaa_devinfo *devinfo;
2267c6b05d2SAlexander Motin 	struct hdaa_pcm_devinfo *pdevinfo;
22788addcbeSAlexander Motin 	uint32_t spd, fmt, fmtlist[32], pcmrates[16];
2287c6b05d2SAlexander Motin 	uint32_t supp_stream_formats, supp_pcm_size_rate;
2296fa8e691SAlexander Motin 	uint32_t blkcnt, blksz;
2307c6b05d2SAlexander Motin 	uint32_t *dmapos;
2317c6b05d2SAlexander Motin 	uint32_t flags;
2327c6b05d2SAlexander Motin 	int dir;
2337c6b05d2SAlexander Motin 	int off;
2347c6b05d2SAlexander Motin 	int sid;
2357c6b05d2SAlexander Motin 	int bit16, bit32;
2367c6b05d2SAlexander Motin 	int channels;	/* Number of audio channels. */
2377c6b05d2SAlexander Motin 	int as;		/* Number of association. */
2387c6b05d2SAlexander Motin 	int asindex;	/* Index within association. */
2397c6b05d2SAlexander Motin 	nid_t io[16];
2406fa8e691SAlexander Motin 	uint8_t	stripecap;	/* AND of stripecap of all ios. */
2416fa8e691SAlexander Motin 	uint8_t	stripectl;	/* stripe to use to all ios. */
2427c6b05d2SAlexander Motin };
2437c6b05d2SAlexander Motin 
2443d741b14SAlexander Motin #define MINQDB(ctl)							\
2453d741b14SAlexander Motin 	((0 - (ctl)->offset) * ((ctl)->size + 1))
2463d741b14SAlexander Motin 
2473d741b14SAlexander Motin #define MAXQDB(ctl)							\
2483d741b14SAlexander Motin 	(((ctl)->step - (ctl)->offset) * ((ctl)->size + 1))
2493d741b14SAlexander Motin 
2503d741b14SAlexander Motin #define RANGEQDB(ctl)							\
2513d741b14SAlexander Motin 	((ctl)->step * ((ctl)->size + 1))
2523d741b14SAlexander Motin 
2533d741b14SAlexander Motin #define VAL2QDB(ctl, val)						\
2543d741b14SAlexander Motin 	(((ctl)->size + 1) * ((int)(val) - (ctl)->offset))
2553d741b14SAlexander Motin 
2563d741b14SAlexander Motin #define QDB2VAL(ctl, qdb)						\
2573d741b14SAlexander Motin 	imax(imin((((qdb) + (ctl)->size / 2 * ((qdb) > 0 ? 1 : -1)) /	\
2583d741b14SAlexander Motin 	 ((ctl)->size + 1) + (ctl)->offset), (ctl)->step), 0)
2593d741b14SAlexander Motin 
2607c6b05d2SAlexander Motin #define hdaa_codec_id(devinfo)						\
2617c6b05d2SAlexander Motin 		(((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) +	\
2627c6b05d2SAlexander Motin 		hda_get_device_id(devinfo->dev))
2637c6b05d2SAlexander Motin 
264ed228e40SAlexander Motin #define hdaa_card_id(devinfo)					\
26589a8feddSAlexander Motin 		(((uint32_t)hda_get_subdevice_id(devinfo->dev) << 16) +	\
26689a8feddSAlexander Motin 		hda_get_subvendor_id(devinfo->dev))
2677c6b05d2SAlexander Motin 
2687c6b05d2SAlexander Motin struct hdaa_widget	*hdaa_widget_get(struct hdaa_devinfo *, nid_t);
2697c6b05d2SAlexander Motin uint32_t		hdaa_widget_pin_patch(uint32_t config, const char *str);
2707c6b05d2SAlexander Motin uint32_t		hdaa_gpio_patch(uint32_t gpio, const char *str);
2717c6b05d2SAlexander Motin 
2727c6b05d2SAlexander Motin void			hdaa_patch(struct hdaa_devinfo *devinfo);
2737c6b05d2SAlexander Motin void			hdaa_patch_direct(struct hdaa_devinfo *devinfo);
2747c6b05d2SAlexander Motin 
2757c6b05d2SAlexander Motin #endif
276