231 lines
6.3 KiB
C
231 lines
6.3 KiB
C
|
/*-7
|
||
|
* Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca>
|
||
|
* Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org>
|
||
|
* Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org>
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
* SUCH DAMAGE.
|
||
|
*
|
||
|
* $FreeBSD$
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
|
||
|
*/
|
||
|
|
||
|
#ifndef _HDAA_QUIRKS_H_
|
||
|
#define _HDAA_QUIRKS_H_
|
||
|
|
||
|
#define HDAA_GPIO_SHIFT(n) (n * 3)
|
||
|
#define HDAA_GPIO_MASK(n) (0x7 << (n * 3))
|
||
|
#define HDAA_GPIO_KEEP(n) (0x0 << (n * 3))
|
||
|
#define HDAA_GPIO_SET(n) (0x1 << (n * 3))
|
||
|
#define HDAA_GPIO_CLEAR(n) (0x2 << (n * 3))
|
||
|
#define HDAA_GPIO_DISABLE(n) (0x3 << (n * 3))
|
||
|
#define HDAA_GPIO_INPUT(n) (0x4 << (n * 3))
|
||
|
|
||
|
/* 9 - 25 = anything else */
|
||
|
#define HDAA_QUIRK_SOFTPCMVOL (1 << 9)
|
||
|
#define HDAA_QUIRK_FIXEDRATE (1 << 10)
|
||
|
#define HDAA_QUIRK_FORCESTEREO (1 << 11)
|
||
|
#define HDAA_QUIRK_EAPDINV (1 << 12)
|
||
|
#define HDAA_QUIRK_SENSEINV (1 << 14)
|
||
|
|
||
|
/* 26 - 31 = vrefs */
|
||
|
#define HDAA_QUIRK_IVREF50 (1 << 26)
|
||
|
#define HDAA_QUIRK_IVREF80 (1 << 27)
|
||
|
#define HDAA_QUIRK_IVREF100 (1 << 28)
|
||
|
#define HDAA_QUIRK_OVREF50 (1 << 29)
|
||
|
#define HDAA_QUIRK_OVREF80 (1 << 30)
|
||
|
#define HDAA_QUIRK_OVREF100 (1 << 31)
|
||
|
|
||
|
#define HDAA_QUIRK_IVREF (HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF80 | \
|
||
|
HDAA_QUIRK_IVREF100)
|
||
|
#define HDAA_QUIRK_OVREF (HDAA_QUIRK_OVREF50 | HDAA_QUIRK_OVREF80 | \
|
||
|
HDAA_QUIRK_OVREF100)
|
||
|
#define HDAA_QUIRK_VREF (HDAA_QUIRK_IVREF | HDAA_QUIRK_OVREF)
|
||
|
|
||
|
#define HDAA_AMP_VOL_DEFAULT (-1)
|
||
|
#define HDAA_AMP_MUTE_DEFAULT (0xffffffff)
|
||
|
#define HDAA_AMP_MUTE_NONE (0)
|
||
|
#define HDAA_AMP_MUTE_LEFT (1 << 0)
|
||
|
#define HDAA_AMP_MUTE_RIGHT (1 << 1)
|
||
|
#define HDAA_AMP_MUTE_ALL (HDAA_AMP_MUTE_LEFT | HDAA_AMP_MUTE_RIGHT)
|
||
|
|
||
|
#define HDAA_AMP_LEFT_MUTED(v) ((v) & (HDAA_AMP_MUTE_LEFT))
|
||
|
#define HDAA_AMP_RIGHT_MUTED(v) (((v) & HDAA_AMP_MUTE_RIGHT) >> 1)
|
||
|
|
||
|
#define HDAA_ADC_MONITOR (1 << 0)
|
||
|
|
||
|
#define HDAA_CTL_OUT 1
|
||
|
#define HDAA_CTL_IN 2
|
||
|
|
||
|
#define HDA_MAX_CONNS 32
|
||
|
#define HDA_MAX_NAMELEN 32
|
||
|
|
||
|
struct hdaa_widget {
|
||
|
nid_t nid;
|
||
|
int type;
|
||
|
int enable;
|
||
|
int nconns, selconn;
|
||
|
int waspin;
|
||
|
uint32_t pflags;
|
||
|
int bindas;
|
||
|
int bindseqmask;
|
||
|
int ossdev;
|
||
|
uint32_t ossmask;
|
||
|
nid_t conns[HDA_MAX_CONNS];
|
||
|
u_char connsenable[HDA_MAX_CONNS];
|
||
|
char name[HDA_MAX_NAMELEN];
|
||
|
struct hdaa_devinfo *devinfo;
|
||
|
struct {
|
||
|
uint32_t widget_cap;
|
||
|
uint32_t outamp_cap;
|
||
|
uint32_t inamp_cap;
|
||
|
uint32_t supp_stream_formats;
|
||
|
uint32_t supp_pcm_size_rate;
|
||
|
uint32_t eapdbtl;
|
||
|
} param;
|
||
|
union {
|
||
|
struct {
|
||
|
uint32_t config;
|
||
|
uint32_t original;
|
||
|
uint32_t newconf;
|
||
|
uint32_t cap;
|
||
|
uint32_t ctrl;
|
||
|
} pin;
|
||
|
} wclass;
|
||
|
};
|
||
|
|
||
|
struct hdaa_audio_ctl {
|
||
|
struct hdaa_widget *widget, *childwidget;
|
||
|
int enable;
|
||
|
int index, dir, ndir;
|
||
|
int mute, step, size, offset;
|
||
|
int left, right, forcemute;
|
||
|
uint32_t muted;
|
||
|
uint32_t ossmask, possmask;
|
||
|
};
|
||
|
|
||
|
/* Association is a group of pins bound for some special function. */
|
||
|
struct hdaa_audio_as {
|
||
|
u_char enable;
|
||
|
u_char index;
|
||
|
u_char dir;
|
||
|
u_char pincnt;
|
||
|
u_char fakeredir;
|
||
|
u_char digital;
|
||
|
uint16_t pinset;
|
||
|
nid_t hpredir;
|
||
|
nid_t pins[16];
|
||
|
nid_t dacs[2][16];
|
||
|
int num_chans;
|
||
|
int chans[2];
|
||
|
int unsol;
|
||
|
int location; /* Pins location, if all have the same */
|
||
|
int mixed; /* Mixed/multiplexed recording, not multichannel. */
|
||
|
};
|
||
|
|
||
|
struct hdaa_pcm_devinfo {
|
||
|
device_t dev;
|
||
|
struct hdaa_devinfo *devinfo;
|
||
|
int index;
|
||
|
int registered;
|
||
|
int playas, recas;
|
||
|
u_char left[SOUND_MIXER_NRDEVICES];
|
||
|
u_char right[SOUND_MIXER_NRDEVICES];
|
||
|
int chan_size;
|
||
|
int chan_blkcnt;
|
||
|
u_char digital;
|
||
|
};
|
||
|
|
||
|
struct hdaa_devinfo {
|
||
|
device_t dev;
|
||
|
struct mtx *lock;
|
||
|
nid_t nid;
|
||
|
nid_t startnode, endnode;
|
||
|
uint32_t outamp_cap;
|
||
|
uint32_t inamp_cap;
|
||
|
uint32_t supp_stream_formats;
|
||
|
uint32_t supp_pcm_size_rate;
|
||
|
uint32_t gpio_cap;
|
||
|
uint32_t quirks;
|
||
|
uint32_t newquirks;
|
||
|
uint32_t gpio;
|
||
|
uint32_t newgpio;
|
||
|
uint32_t gpo;
|
||
|
uint32_t newgpo;
|
||
|
int nodecnt;
|
||
|
int ctlcnt;
|
||
|
int ascnt;
|
||
|
int num_devs;
|
||
|
int num_chans;
|
||
|
struct hdaa_widget *widget;
|
||
|
struct hdaa_audio_ctl *ctl;
|
||
|
struct hdaa_audio_as *as;
|
||
|
struct hdaa_pcm_devinfo *devs;
|
||
|
struct hdaa_chan *chans;
|
||
|
struct callout poll_jack;
|
||
|
int poll_ival;
|
||
|
};
|
||
|
|
||
|
#define HDAA_CHN_RUNNING 0x00000001
|
||
|
#define HDAA_CHN_SUSPEND 0x00000002
|
||
|
|
||
|
struct hdaa_chan {
|
||
|
struct snd_dbuf *b;
|
||
|
struct pcm_channel *c;
|
||
|
struct pcmchan_caps caps;
|
||
|
struct hdaa_devinfo *devinfo;
|
||
|
struct hdaa_pcm_devinfo *pdevinfo;
|
||
|
uint32_t spd, fmt, fmtlist[16], pcmrates[16];
|
||
|
uint32_t supp_stream_formats, supp_pcm_size_rate;
|
||
|
uint32_t ptr, prevptr, blkcnt, blksz;
|
||
|
uint32_t *dmapos;
|
||
|
uint32_t flags;
|
||
|
int dir;
|
||
|
int off;
|
||
|
int sid;
|
||
|
int bit16, bit32;
|
||
|
int channels; /* Number of audio channels. */
|
||
|
int as; /* Number of association. */
|
||
|
int asindex; /* Index within association. */
|
||
|
nid_t io[16];
|
||
|
};
|
||
|
|
||
|
#define hdaa_codec_id(devinfo) \
|
||
|
(((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) + \
|
||
|
hda_get_device_id(devinfo->dev))
|
||
|
|
||
|
#define hdaa_subvendor_id(devinfo) \
|
||
|
(((uint32_t)hda_get_subvendor_id(devinfo->dev) << 16) + \
|
||
|
hda_get_subdevice_id(devinfo->dev))
|
||
|
|
||
|
struct hdaa_widget *hdaa_widget_get(struct hdaa_devinfo *, nid_t);
|
||
|
uint32_t hdaa_widget_pin_patch(uint32_t config, const char *str);
|
||
|
uint32_t hdaa_gpio_patch(uint32_t gpio, const char *str);
|
||
|
|
||
|
void hdaa_patch(struct hdaa_devinfo *devinfo);
|
||
|
void hdaa_patch_direct(struct hdaa_devinfo *devinfo);
|
||
|
|
||
|
#endif
|