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