17c6b05d2SAlexander Motin /*-7 27c6b05d2SAlexander Motin * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> 37c6b05d2SAlexander Motin * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org> 47c6b05d2SAlexander Motin * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org> 57c6b05d2SAlexander Motin * All rights reserved. 67c6b05d2SAlexander Motin * 77c6b05d2SAlexander Motin * Redistribution and use in source and binary forms, with or without 87c6b05d2SAlexander Motin * modification, are permitted provided that the following conditions 97c6b05d2SAlexander Motin * are met: 107c6b05d2SAlexander Motin * 1. Redistributions of source code must retain the above copyright 117c6b05d2SAlexander Motin * notice, this list of conditions and the following disclaimer. 127c6b05d2SAlexander Motin * 2. Redistributions in binary form must reproduce the above copyright 137c6b05d2SAlexander Motin * notice, this list of conditions and the following disclaimer in the 147c6b05d2SAlexander Motin * documentation and/or other materials provided with the distribution. 157c6b05d2SAlexander Motin * 167c6b05d2SAlexander Motin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 177c6b05d2SAlexander Motin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 187c6b05d2SAlexander Motin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 197c6b05d2SAlexander Motin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 207c6b05d2SAlexander Motin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 217c6b05d2SAlexander Motin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 227c6b05d2SAlexander Motin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 237c6b05d2SAlexander Motin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 247c6b05d2SAlexander Motin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 257c6b05d2SAlexander Motin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 267c6b05d2SAlexander Motin * SUCH DAMAGE. 277c6b05d2SAlexander Motin * 287c6b05d2SAlexander Motin * $FreeBSD$ 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) 597c6b05d2SAlexander Motin #define HDAA_QUIRK_OVREF100 (1 << 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 77*3d741b14SAlexander Motin /* Widget in playback receiving signal from recording. */ 787c6b05d2SAlexander Motin #define HDAA_ADC_MONITOR (1 << 0) 79*3d741b14SAlexander Motin /* Input mixer widget needs volume control as destination. */ 80*3d741b14SAlexander 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 88*3d741b14SAlexander Motin struct hdaa_audio_as; 89*3d741b14SAlexander Motin struct hdaa_audio_ctl; 90*3d741b14SAlexander Motin struct hdaa_chan; 91*3d741b14SAlexander Motin struct hdaa_devinfo; 92*3d741b14SAlexander Motin struct hdaa_pcm_devinfo; 93*3d741b14SAlexander Motin struct hdaa_widget; 94*3d741b14SAlexander 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; 1287c6b05d2SAlexander Motin } pin; 1296fa8e691SAlexander Motin struct { 1306fa8e691SAlexander Motin uint8_t stripecap; 1316fa8e691SAlexander Motin } conv; 1327c6b05d2SAlexander Motin } wclass; 1337c6b05d2SAlexander Motin }; 1347c6b05d2SAlexander Motin 1357c6b05d2SAlexander Motin struct hdaa_audio_ctl { 1367c6b05d2SAlexander Motin struct hdaa_widget *widget, *childwidget; 1377c6b05d2SAlexander Motin int enable; 1387c6b05d2SAlexander Motin int index, dir, ndir; 1397c6b05d2SAlexander Motin int mute, step, size, offset; 1407c6b05d2SAlexander Motin int left, right, forcemute; 1417c6b05d2SAlexander Motin uint32_t muted; 142*3d741b14SAlexander Motin uint32_t ossmask; /* OSS devices that may affect control. */ 143*3d741b14SAlexander Motin int devleft[SOUND_MIXER_NRDEVICES]; /* Left ampl in 1/4dB. */ 144*3d741b14SAlexander Motin int devright[SOUND_MIXER_NRDEVICES]; /* Right ampl in 1/4dB. */ 145*3d741b14SAlexander Motin int devmute[SOUND_MIXER_NRDEVICES]; /* Mutes per OSS device. */ 1467c6b05d2SAlexander Motin }; 1477c6b05d2SAlexander Motin 1487c6b05d2SAlexander Motin /* Association is a group of pins bound for some special function. */ 1497c6b05d2SAlexander Motin struct hdaa_audio_as { 1507c6b05d2SAlexander Motin u_char enable; 1517c6b05d2SAlexander Motin u_char index; 1527c6b05d2SAlexander Motin u_char dir; 1537c6b05d2SAlexander Motin u_char pincnt; 1547c6b05d2SAlexander Motin u_char fakeredir; 1557c6b05d2SAlexander Motin u_char digital; 1567c6b05d2SAlexander Motin uint16_t pinset; 1577c6b05d2SAlexander Motin nid_t hpredir; 1587c6b05d2SAlexander Motin nid_t pins[16]; 1597c6b05d2SAlexander Motin nid_t dacs[2][16]; 1607c6b05d2SAlexander Motin int num_chans; 1617c6b05d2SAlexander Motin int chans[2]; 1627c6b05d2SAlexander Motin int location; /* Pins location, if all have the same */ 1637c6b05d2SAlexander Motin int mixed; /* Mixed/multiplexed recording, not multichannel. */ 164*3d741b14SAlexander Motin struct hdaa_pcm_devinfo *pdevinfo; 1657c6b05d2SAlexander Motin }; 1667c6b05d2SAlexander Motin 1677c6b05d2SAlexander Motin struct hdaa_pcm_devinfo { 1687c6b05d2SAlexander Motin device_t dev; 1697c6b05d2SAlexander Motin struct hdaa_devinfo *devinfo; 170*3d741b14SAlexander Motin struct snd_mixer *mixer; 1717c6b05d2SAlexander Motin int index; 1727c6b05d2SAlexander Motin int registered; 1737c6b05d2SAlexander Motin int playas, recas; 1747c6b05d2SAlexander Motin u_char left[SOUND_MIXER_NRDEVICES]; 1757c6b05d2SAlexander Motin u_char right[SOUND_MIXER_NRDEVICES]; 176*3d741b14SAlexander Motin int minamp[SOUND_MIXER_NRDEVICES]; /* Minimal amps in 1/4dB. */ 177*3d741b14SAlexander Motin int maxamp[SOUND_MIXER_NRDEVICES]; /* Maximal amps in 1/4dB. */ 1787c6b05d2SAlexander Motin int chan_size; 1797c6b05d2SAlexander Motin int chan_blkcnt; 1807c6b05d2SAlexander Motin u_char digital; 181*3d741b14SAlexander Motin uint32_t ossmask; /* Mask of supported OSS devices. */ 182*3d741b14SAlexander Motin uint32_t recsrc; /* Mask of supported OSS sources. */ 1837c6b05d2SAlexander Motin }; 1847c6b05d2SAlexander Motin 1857c6b05d2SAlexander Motin struct hdaa_devinfo { 1867c6b05d2SAlexander Motin device_t dev; 1877c6b05d2SAlexander Motin struct mtx *lock; 1887c6b05d2SAlexander Motin nid_t nid; 1897c6b05d2SAlexander Motin nid_t startnode, endnode; 1907c6b05d2SAlexander Motin uint32_t outamp_cap; 1917c6b05d2SAlexander Motin uint32_t inamp_cap; 1927c6b05d2SAlexander Motin uint32_t supp_stream_formats; 1937c6b05d2SAlexander Motin uint32_t supp_pcm_size_rate; 1947c6b05d2SAlexander Motin uint32_t gpio_cap; 1957c6b05d2SAlexander Motin uint32_t quirks; 1967c6b05d2SAlexander Motin uint32_t newquirks; 1977c6b05d2SAlexander Motin uint32_t gpio; 1987c6b05d2SAlexander Motin uint32_t newgpio; 1997c6b05d2SAlexander Motin uint32_t gpo; 2007c6b05d2SAlexander Motin uint32_t newgpo; 2017c6b05d2SAlexander Motin int nodecnt; 2027c6b05d2SAlexander Motin int ctlcnt; 2037c6b05d2SAlexander Motin int ascnt; 2047c6b05d2SAlexander Motin int num_devs; 2057c6b05d2SAlexander Motin int num_chans; 2067c6b05d2SAlexander Motin struct hdaa_widget *widget; 2077c6b05d2SAlexander Motin struct hdaa_audio_ctl *ctl; 2087c6b05d2SAlexander Motin struct hdaa_audio_as *as; 2097c6b05d2SAlexander Motin struct hdaa_pcm_devinfo *devs; 2107c6b05d2SAlexander Motin struct hdaa_chan *chans; 2117c6b05d2SAlexander Motin struct callout poll_jack; 2127c6b05d2SAlexander Motin int poll_ival; 2137c6b05d2SAlexander Motin }; 2147c6b05d2SAlexander Motin 2157c6b05d2SAlexander Motin #define HDAA_CHN_RUNNING 0x00000001 2167c6b05d2SAlexander Motin #define HDAA_CHN_SUSPEND 0x00000002 2177c6b05d2SAlexander Motin 2187c6b05d2SAlexander Motin struct hdaa_chan { 2197c6b05d2SAlexander Motin struct snd_dbuf *b; 2207c6b05d2SAlexander Motin struct pcm_channel *c; 2217c6b05d2SAlexander Motin struct pcmchan_caps caps; 2227c6b05d2SAlexander Motin struct hdaa_devinfo *devinfo; 2237c6b05d2SAlexander Motin struct hdaa_pcm_devinfo *pdevinfo; 22488addcbeSAlexander Motin uint32_t spd, fmt, fmtlist[32], pcmrates[16]; 2257c6b05d2SAlexander Motin uint32_t supp_stream_formats, supp_pcm_size_rate; 2266fa8e691SAlexander Motin uint32_t blkcnt, blksz; 2277c6b05d2SAlexander Motin uint32_t *dmapos; 2287c6b05d2SAlexander Motin uint32_t flags; 2297c6b05d2SAlexander Motin int dir; 2307c6b05d2SAlexander Motin int off; 2317c6b05d2SAlexander Motin int sid; 2327c6b05d2SAlexander Motin int bit16, bit32; 2337c6b05d2SAlexander Motin int channels; /* Number of audio channels. */ 2347c6b05d2SAlexander Motin int as; /* Number of association. */ 2357c6b05d2SAlexander Motin int asindex; /* Index within association. */ 2367c6b05d2SAlexander Motin nid_t io[16]; 2376fa8e691SAlexander Motin uint8_t stripecap; /* AND of stripecap of all ios. */ 2386fa8e691SAlexander Motin uint8_t stripectl; /* stripe to use to all ios. */ 2397c6b05d2SAlexander Motin }; 2407c6b05d2SAlexander Motin 241*3d741b14SAlexander Motin #define MINQDB(ctl) \ 242*3d741b14SAlexander Motin ((0 - (ctl)->offset) * ((ctl)->size + 1)) 243*3d741b14SAlexander Motin 244*3d741b14SAlexander Motin #define MAXQDB(ctl) \ 245*3d741b14SAlexander Motin (((ctl)->step - (ctl)->offset) * ((ctl)->size + 1)) 246*3d741b14SAlexander Motin 247*3d741b14SAlexander Motin #define RANGEQDB(ctl) \ 248*3d741b14SAlexander Motin ((ctl)->step * ((ctl)->size + 1)) 249*3d741b14SAlexander Motin 250*3d741b14SAlexander Motin #define VAL2QDB(ctl, val) \ 251*3d741b14SAlexander Motin (((ctl)->size + 1) * ((int)(val) - (ctl)->offset)) 252*3d741b14SAlexander Motin 253*3d741b14SAlexander Motin #define QDB2VAL(ctl, qdb) \ 254*3d741b14SAlexander Motin imax(imin((((qdb) + (ctl)->size / 2 * ((qdb) > 0 ? 1 : -1)) / \ 255*3d741b14SAlexander Motin ((ctl)->size + 1) + (ctl)->offset), (ctl)->step), 0) 256*3d741b14SAlexander Motin 2577c6b05d2SAlexander Motin #define hdaa_codec_id(devinfo) \ 2587c6b05d2SAlexander Motin (((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) + \ 2597c6b05d2SAlexander Motin hda_get_device_id(devinfo->dev)) 2607c6b05d2SAlexander Motin 2617c6b05d2SAlexander Motin #define hdaa_subvendor_id(devinfo) \ 2627c6b05d2SAlexander Motin (((uint32_t)hda_get_subvendor_id(devinfo->dev) << 16) + \ 2637c6b05d2SAlexander Motin hda_get_subdevice_id(devinfo->dev)) 2647c6b05d2SAlexander Motin 2657c6b05d2SAlexander Motin struct hdaa_widget *hdaa_widget_get(struct hdaa_devinfo *, nid_t); 2667c6b05d2SAlexander Motin uint32_t hdaa_widget_pin_patch(uint32_t config, const char *str); 2677c6b05d2SAlexander Motin uint32_t hdaa_gpio_patch(uint32_t gpio, const char *str); 2687c6b05d2SAlexander Motin 2697c6b05d2SAlexander Motin void hdaa_patch(struct hdaa_devinfo *devinfo); 2707c6b05d2SAlexander Motin void hdaa_patch_direct(struct hdaa_devinfo *devinfo); 2717c6b05d2SAlexander Motin 2727c6b05d2SAlexander Motin #endif 273