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 777c6b05d2SAlexander Motin #define HDAA_ADC_MONITOR (1 << 0) 787c6b05d2SAlexander Motin 797c6b05d2SAlexander Motin #define HDAA_CTL_OUT 1 807c6b05d2SAlexander Motin #define HDAA_CTL_IN 2 817c6b05d2SAlexander Motin 827c6b05d2SAlexander Motin #define HDA_MAX_CONNS 32 837c6b05d2SAlexander Motin #define HDA_MAX_NAMELEN 32 847c6b05d2SAlexander Motin 857c6b05d2SAlexander Motin struct hdaa_widget { 867c6b05d2SAlexander Motin nid_t nid; 877c6b05d2SAlexander Motin int type; 887c6b05d2SAlexander Motin int enable; 897c6b05d2SAlexander Motin int nconns, selconn; 907c6b05d2SAlexander Motin int waspin; 917c6b05d2SAlexander Motin uint32_t pflags; 927c6b05d2SAlexander Motin int bindas; 937c6b05d2SAlexander Motin int bindseqmask; 947c6b05d2SAlexander Motin int ossdev; 957c6b05d2SAlexander Motin uint32_t ossmask; 96*88addcbeSAlexander Motin int unsol; 977c6b05d2SAlexander Motin nid_t conns[HDA_MAX_CONNS]; 987c6b05d2SAlexander Motin u_char connsenable[HDA_MAX_CONNS]; 997c6b05d2SAlexander Motin char name[HDA_MAX_NAMELEN]; 100*88addcbeSAlexander Motin uint8_t *eld; 101*88addcbeSAlexander Motin int eld_len; 1027c6b05d2SAlexander Motin struct hdaa_devinfo *devinfo; 1037c6b05d2SAlexander Motin struct { 1047c6b05d2SAlexander Motin uint32_t widget_cap; 1057c6b05d2SAlexander Motin uint32_t outamp_cap; 1067c6b05d2SAlexander Motin uint32_t inamp_cap; 1077c6b05d2SAlexander Motin uint32_t supp_stream_formats; 1087c6b05d2SAlexander Motin uint32_t supp_pcm_size_rate; 1097c6b05d2SAlexander Motin uint32_t eapdbtl; 1107c6b05d2SAlexander Motin } param; 1117c6b05d2SAlexander Motin union { 1127c6b05d2SAlexander Motin struct { 1137c6b05d2SAlexander Motin uint32_t config; 1147c6b05d2SAlexander Motin uint32_t original; 1157c6b05d2SAlexander Motin uint32_t newconf; 1167c6b05d2SAlexander Motin uint32_t cap; 1177c6b05d2SAlexander Motin uint32_t ctrl; 1187c6b05d2SAlexander Motin } pin; 1197c6b05d2SAlexander Motin } wclass; 1207c6b05d2SAlexander Motin }; 1217c6b05d2SAlexander Motin 1227c6b05d2SAlexander Motin struct hdaa_audio_ctl { 1237c6b05d2SAlexander Motin struct hdaa_widget *widget, *childwidget; 1247c6b05d2SAlexander Motin int enable; 1257c6b05d2SAlexander Motin int index, dir, ndir; 1267c6b05d2SAlexander Motin int mute, step, size, offset; 1277c6b05d2SAlexander Motin int left, right, forcemute; 1287c6b05d2SAlexander Motin uint32_t muted; 1297c6b05d2SAlexander Motin uint32_t ossmask, possmask; 1307c6b05d2SAlexander Motin }; 1317c6b05d2SAlexander Motin 1327c6b05d2SAlexander Motin /* Association is a group of pins bound for some special function. */ 1337c6b05d2SAlexander Motin struct hdaa_audio_as { 1347c6b05d2SAlexander Motin u_char enable; 1357c6b05d2SAlexander Motin u_char index; 1367c6b05d2SAlexander Motin u_char dir; 1377c6b05d2SAlexander Motin u_char pincnt; 1387c6b05d2SAlexander Motin u_char fakeredir; 1397c6b05d2SAlexander Motin u_char digital; 1407c6b05d2SAlexander Motin uint16_t pinset; 1417c6b05d2SAlexander Motin nid_t hpredir; 1427c6b05d2SAlexander Motin nid_t pins[16]; 1437c6b05d2SAlexander Motin nid_t dacs[2][16]; 1447c6b05d2SAlexander Motin int num_chans; 1457c6b05d2SAlexander Motin int chans[2]; 1467c6b05d2SAlexander Motin int location; /* Pins location, if all have the same */ 1477c6b05d2SAlexander Motin int mixed; /* Mixed/multiplexed recording, not multichannel. */ 1487c6b05d2SAlexander Motin }; 1497c6b05d2SAlexander Motin 1507c6b05d2SAlexander Motin struct hdaa_pcm_devinfo { 1517c6b05d2SAlexander Motin device_t dev; 1527c6b05d2SAlexander Motin struct hdaa_devinfo *devinfo; 1537c6b05d2SAlexander Motin int index; 1547c6b05d2SAlexander Motin int registered; 1557c6b05d2SAlexander Motin int playas, recas; 1567c6b05d2SAlexander Motin u_char left[SOUND_MIXER_NRDEVICES]; 1577c6b05d2SAlexander Motin u_char right[SOUND_MIXER_NRDEVICES]; 1587c6b05d2SAlexander Motin int chan_size; 1597c6b05d2SAlexander Motin int chan_blkcnt; 1607c6b05d2SAlexander Motin u_char digital; 1617c6b05d2SAlexander Motin }; 1627c6b05d2SAlexander Motin 1637c6b05d2SAlexander Motin struct hdaa_devinfo { 1647c6b05d2SAlexander Motin device_t dev; 1657c6b05d2SAlexander Motin struct mtx *lock; 1667c6b05d2SAlexander Motin nid_t nid; 1677c6b05d2SAlexander Motin nid_t startnode, endnode; 1687c6b05d2SAlexander Motin uint32_t outamp_cap; 1697c6b05d2SAlexander Motin uint32_t inamp_cap; 1707c6b05d2SAlexander Motin uint32_t supp_stream_formats; 1717c6b05d2SAlexander Motin uint32_t supp_pcm_size_rate; 1727c6b05d2SAlexander Motin uint32_t gpio_cap; 1737c6b05d2SAlexander Motin uint32_t quirks; 1747c6b05d2SAlexander Motin uint32_t newquirks; 1757c6b05d2SAlexander Motin uint32_t gpio; 1767c6b05d2SAlexander Motin uint32_t newgpio; 1777c6b05d2SAlexander Motin uint32_t gpo; 1787c6b05d2SAlexander Motin uint32_t newgpo; 1797c6b05d2SAlexander Motin int nodecnt; 1807c6b05d2SAlexander Motin int ctlcnt; 1817c6b05d2SAlexander Motin int ascnt; 1827c6b05d2SAlexander Motin int num_devs; 1837c6b05d2SAlexander Motin int num_chans; 1847c6b05d2SAlexander Motin struct hdaa_widget *widget; 1857c6b05d2SAlexander Motin struct hdaa_audio_ctl *ctl; 1867c6b05d2SAlexander Motin struct hdaa_audio_as *as; 1877c6b05d2SAlexander Motin struct hdaa_pcm_devinfo *devs; 1887c6b05d2SAlexander Motin struct hdaa_chan *chans; 1897c6b05d2SAlexander Motin struct callout poll_jack; 1907c6b05d2SAlexander Motin int poll_ival; 1917c6b05d2SAlexander Motin }; 1927c6b05d2SAlexander Motin 1937c6b05d2SAlexander Motin #define HDAA_CHN_RUNNING 0x00000001 1947c6b05d2SAlexander Motin #define HDAA_CHN_SUSPEND 0x00000002 1957c6b05d2SAlexander Motin 1967c6b05d2SAlexander Motin struct hdaa_chan { 1977c6b05d2SAlexander Motin struct snd_dbuf *b; 1987c6b05d2SAlexander Motin struct pcm_channel *c; 1997c6b05d2SAlexander Motin struct pcmchan_caps caps; 2007c6b05d2SAlexander Motin struct hdaa_devinfo *devinfo; 2017c6b05d2SAlexander Motin struct hdaa_pcm_devinfo *pdevinfo; 202*88addcbeSAlexander Motin uint32_t spd, fmt, fmtlist[32], pcmrates[16]; 2037c6b05d2SAlexander Motin uint32_t supp_stream_formats, supp_pcm_size_rate; 2047c6b05d2SAlexander Motin uint32_t ptr, prevptr, blkcnt, blksz; 2057c6b05d2SAlexander Motin uint32_t *dmapos; 2067c6b05d2SAlexander Motin uint32_t flags; 2077c6b05d2SAlexander Motin int dir; 2087c6b05d2SAlexander Motin int off; 2097c6b05d2SAlexander Motin int sid; 2107c6b05d2SAlexander Motin int bit16, bit32; 2117c6b05d2SAlexander Motin int channels; /* Number of audio channels. */ 2127c6b05d2SAlexander Motin int as; /* Number of association. */ 2137c6b05d2SAlexander Motin int asindex; /* Index within association. */ 2147c6b05d2SAlexander Motin nid_t io[16]; 2157c6b05d2SAlexander Motin }; 2167c6b05d2SAlexander Motin 2177c6b05d2SAlexander Motin #define hdaa_codec_id(devinfo) \ 2187c6b05d2SAlexander Motin (((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) + \ 2197c6b05d2SAlexander Motin hda_get_device_id(devinfo->dev)) 2207c6b05d2SAlexander Motin 2217c6b05d2SAlexander Motin #define hdaa_subvendor_id(devinfo) \ 2227c6b05d2SAlexander Motin (((uint32_t)hda_get_subvendor_id(devinfo->dev) << 16) + \ 2237c6b05d2SAlexander Motin hda_get_subdevice_id(devinfo->dev)) 2247c6b05d2SAlexander Motin 2257c6b05d2SAlexander Motin struct hdaa_widget *hdaa_widget_get(struct hdaa_devinfo *, nid_t); 2267c6b05d2SAlexander Motin uint32_t hdaa_widget_pin_patch(uint32_t config, const char *str); 2277c6b05d2SAlexander Motin uint32_t hdaa_gpio_patch(uint32_t gpio, const char *str); 2287c6b05d2SAlexander Motin 2297c6b05d2SAlexander Motin void hdaa_patch(struct hdaa_devinfo *devinfo); 2307c6b05d2SAlexander Motin void hdaa_patch_direct(struct hdaa_devinfo *devinfo); 2317c6b05d2SAlexander Motin 2327c6b05d2SAlexander Motin #endif 233