freebsd-dev/sys/dev/sound/pci/hda/hdaa.c

6802 lines
186 KiB
C
Raw Normal View History

Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/*-
* 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.
*/
/*
* Intel High Definition Audio (Audio function) driver for FreeBSD.
*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_snd.h"
#endif
#include <dev/sound/pcm/sound.h>
#include <sys/ctype.h>
#include <sys/taskqueue.h>
#include <dev/sound/pci/hda/hdac.h>
#include <dev/sound/pci/hda/hdaa.h>
#include <dev/sound/pci/hda/hda_reg.h>
#include "mixer_if.h"
SND_DECLARE_FILE("$FreeBSD$");
#define hdaa_lock(devinfo) snd_mtxlock((devinfo)->lock)
#define hdaa_unlock(devinfo) snd_mtxunlock((devinfo)->lock)
#define hdaa_lockassert(devinfo) snd_mtxassert((devinfo)->lock)
#define hdaa_lockowned(devinfo) mtx_owned((devinfo)->lock)
static const struct {
char *key;
uint32_t value;
} hdaa_quirks_tab[] = {
{ "softpcmvol", HDAA_QUIRK_SOFTPCMVOL },
{ "fixedrate", HDAA_QUIRK_FIXEDRATE },
{ "forcestereo", HDAA_QUIRK_FORCESTEREO },
{ "eapdinv", HDAA_QUIRK_EAPDINV },
{ "senseinv", HDAA_QUIRK_SENSEINV },
{ "ivref50", HDAA_QUIRK_IVREF50 },
{ "ivref80", HDAA_QUIRK_IVREF80 },
{ "ivref100", HDAA_QUIRK_IVREF100 },
{ "ovref50", HDAA_QUIRK_OVREF50 },
{ "ovref80", HDAA_QUIRK_OVREF80 },
{ "ovref100", HDAA_QUIRK_OVREF100 },
{ "ivref", HDAA_QUIRK_IVREF },
{ "ovref", HDAA_QUIRK_OVREF },
{ "vref", HDAA_QUIRK_VREF },
};
#define HDAA_QUIRKS_TAB_LEN \
(sizeof(hdaa_quirks_tab) / sizeof(hdaa_quirks_tab[0]))
#define HDA_PARSE_MAXDEPTH 10
MALLOC_DEFINE(M_HDAA, "hdaa", "HDA Audio");
const char *HDA_COLORS[16] = {"Unknown", "Black", "Grey", "Blue", "Green", "Red",
"Orange", "Yellow", "Purple", "Pink", "Res.A", "Res.B", "Res.C", "Res.D",
"White", "Other"};
const char *HDA_DEVS[16] = {"Line-out", "Speaker", "Headphones", "CD",
"SPDIF-out", "Digital-out", "Modem-line", "Modem-handset", "Line-in",
"AUX", "Mic", "Telephony", "SPDIF-in", "Digital-in", "Res.E", "Other"};
const char *HDA_CONNS[4] = {"Jack", "None", "Fixed", "Both"};
const char *HDA_CONNECTORS[16] = {
"Unknown", "1/8", "1/4", "ATAPI", "RCA", "Optical", "Digital", "Analog",
"DIN", "XLR", "RJ-11", "Combo", "0xc", "0xd", "0xe", "Other" };
const char *HDA_LOCS[64] = {
"0x00", "Rear", "Front", "Left", "Right", "Top", "Bottom", "Rear-panel",
"Drive-bay", "0x09", "0x0a", "0x0b", "0x0c", "0x0d", "0x0e", "0x0f",
"Internal", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "Riser",
"0x18", "Onboard", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f",
"External", "Ext-Rear", "Ext-Front", "Ext-Left", "Ext-Right", "Ext-Top", "Ext-Bottom", "0x07",
"0x28", "0x29", "0x2a", "0x2b", "0x2c", "0x2d", "0x2e", "0x2f",
"Other", "0x31", "0x32", "0x33", "0x34", "0x35", "Other-Bott", "Lid-In",
"Lid-Out", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f" };
const char *HDA_GPIO_ACTIONS[8] = {
"keep", "set", "clear", "disable", "input", "0x05", "0x06", "0x07"};
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
const char *HDA_HDMI_CODING_TYPES[18] = {
"undefined", "LPCM", "AC-3", "MPEG1", "MP3", "MPEG2", "AAC-LC", "DTS",
"ATRAC", "DSD", "E-AC-3", "DTS-HD", "MLP", "DST", "WMAPro", "HE-AAC",
"HE-AACv2", "MPEG-Surround"
};
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Default */
static uint32_t hdaa_fmt[] = {
SND_FORMAT(AFMT_S16_LE, 2, 0),
0
};
static struct pcmchan_caps hdaa_caps = {48000, 48000, hdaa_fmt, 0};
static const struct {
uint32_t rate;
int valid;
uint16_t base;
uint16_t mul;
uint16_t div;
} hda_rate_tab[] = {
{ 8000, 1, 0x0000, 0x0000, 0x0500 }, /* (48000 * 1) / 6 */
{ 9600, 0, 0x0000, 0x0000, 0x0400 }, /* (48000 * 1) / 5 */
{ 12000, 0, 0x0000, 0x0000, 0x0300 }, /* (48000 * 1) / 4 */
{ 16000, 1, 0x0000, 0x0000, 0x0200 }, /* (48000 * 1) / 3 */
{ 18000, 0, 0x0000, 0x1000, 0x0700 }, /* (48000 * 3) / 8 */
{ 19200, 0, 0x0000, 0x0800, 0x0400 }, /* (48000 * 2) / 5 */
{ 24000, 0, 0x0000, 0x0000, 0x0100 }, /* (48000 * 1) / 2 */
{ 28800, 0, 0x0000, 0x1000, 0x0400 }, /* (48000 * 3) / 5 */
{ 32000, 1, 0x0000, 0x0800, 0x0200 }, /* (48000 * 2) / 3 */
{ 36000, 0, 0x0000, 0x1000, 0x0300 }, /* (48000 * 3) / 4 */
{ 38400, 0, 0x0000, 0x1800, 0x0400 }, /* (48000 * 4) / 5 */
{ 48000, 1, 0x0000, 0x0000, 0x0000 }, /* (48000 * 1) / 1 */
{ 64000, 0, 0x0000, 0x1800, 0x0200 }, /* (48000 * 4) / 3 */
{ 72000, 0, 0x0000, 0x1000, 0x0100 }, /* (48000 * 3) / 2 */
{ 96000, 1, 0x0000, 0x0800, 0x0000 }, /* (48000 * 2) / 1 */
{ 144000, 0, 0x0000, 0x1000, 0x0000 }, /* (48000 * 3) / 1 */
{ 192000, 1, 0x0000, 0x1800, 0x0000 }, /* (48000 * 4) / 1 */
{ 8820, 0, 0x4000, 0x0000, 0x0400 }, /* (44100 * 1) / 5 */
{ 11025, 1, 0x4000, 0x0000, 0x0300 }, /* (44100 * 1) / 4 */
{ 12600, 0, 0x4000, 0x0800, 0x0600 }, /* (44100 * 2) / 7 */
{ 14700, 0, 0x4000, 0x0000, 0x0200 }, /* (44100 * 1) / 3 */
{ 17640, 0, 0x4000, 0x0800, 0x0400 }, /* (44100 * 2) / 5 */
{ 18900, 0, 0x4000, 0x1000, 0x0600 }, /* (44100 * 3) / 7 */
{ 22050, 1, 0x4000, 0x0000, 0x0100 }, /* (44100 * 1) / 2 */
{ 25200, 0, 0x4000, 0x1800, 0x0600 }, /* (44100 * 4) / 7 */
{ 26460, 0, 0x4000, 0x1000, 0x0400 }, /* (44100 * 3) / 5 */
{ 29400, 0, 0x4000, 0x0800, 0x0200 }, /* (44100 * 2) / 3 */
{ 33075, 0, 0x4000, 0x1000, 0x0300 }, /* (44100 * 3) / 4 */
{ 35280, 0, 0x4000, 0x1800, 0x0400 }, /* (44100 * 4) / 5 */
{ 44100, 1, 0x4000, 0x0000, 0x0000 }, /* (44100 * 1) / 1 */
{ 58800, 0, 0x4000, 0x1800, 0x0200 }, /* (44100 * 4) / 3 */
{ 66150, 0, 0x4000, 0x1000, 0x0100 }, /* (44100 * 3) / 2 */
{ 88200, 1, 0x4000, 0x0800, 0x0000 }, /* (44100 * 2) / 1 */
{ 132300, 0, 0x4000, 0x1000, 0x0000 }, /* (44100 * 3) / 1 */
{ 176400, 1, 0x4000, 0x1800, 0x0000 }, /* (44100 * 4) / 1 */
};
#define HDA_RATE_TAB_LEN (sizeof(hda_rate_tab) / sizeof(hda_rate_tab[0]))
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
const static char *ossnames[] = SOUND_DEVICE_NAMES;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/****************************************************************************
* Function prototypes
****************************************************************************/
static int hdaa_pcmchannel_setup(struct hdaa_chan *);
static void hdaa_widget_connection_select(struct hdaa_widget *, uint8_t);
static void hdaa_audio_ctl_amp_set(struct hdaa_audio_ctl *,
uint32_t, int, int);
static struct hdaa_audio_ctl *hdaa_audio_ctl_amp_get(struct hdaa_devinfo *,
nid_t, int, int, int);
static void hdaa_audio_ctl_amp_set_internal(struct hdaa_devinfo *,
nid_t, int, int, int, int, int, int);
static void hdaa_dump_pin_config(struct hdaa_widget *w, uint32_t conf);
static char *
hdaa_audio_ctl_ossmixer_mask2allname(uint32_t mask, char *buf, size_t len)
{
int i, first = 1;
bzero(buf, len);
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
if (mask & (1 << i)) {
if (first == 0)
strlcat(buf, ", ", len);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
strlcat(buf, ossnames[i], len);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
first = 0;
}
}
return (buf);
}
static struct hdaa_audio_ctl *
hdaa_audio_ctl_each(struct hdaa_devinfo *devinfo, int *index)
{
if (devinfo == NULL ||
index == NULL || devinfo->ctl == NULL ||
devinfo->ctlcnt < 1 ||
*index < 0 || *index >= devinfo->ctlcnt)
return (NULL);
return (&devinfo->ctl[(*index)++]);
}
static struct hdaa_audio_ctl *
hdaa_audio_ctl_amp_get(struct hdaa_devinfo *devinfo, nid_t nid, int dir,
int index, int cnt)
{
struct hdaa_audio_ctl *ctl;
int i, found = 0;
if (devinfo == NULL || devinfo->ctl == NULL)
return (NULL);
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0)
continue;
if (ctl->widget->nid != nid)
continue;
if (dir && ctl->ndir != dir)
continue;
if (index >= 0 && ctl->ndir == HDAA_CTL_IN &&
ctl->dir == ctl->ndir && ctl->index != index)
continue;
found++;
if (found == cnt || cnt <= 0)
return (ctl);
}
return (NULL);
}
/*
* Headphones redirection change handler.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
static void
hdaa_hpredir_handler(struct hdaa_widget *w)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
struct hdaa_devinfo *devinfo = w->devinfo;
struct hdaa_audio_as *as = &devinfo->as[w->bindas];
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
struct hdaa_widget *w1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
struct hdaa_audio_ctl *ctl;
uint32_t val;
int j, connected = w->wclass.pin.connected;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
HDA_BOOTVERBOSE(
device_printf((as->pdevinfo && as->pdevinfo->dev) ?
as->pdevinfo->dev : devinfo->dev,
"Redirect output to: %s\n",
connected ? "headphones": "main");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
);
/* (Un)Mute headphone pin. */
ctl = hdaa_audio_ctl_amp_get(devinfo,
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
w->nid, HDAA_CTL_IN, -1, 1);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (ctl != NULL && ctl->mute) {
/* If pin has muter - use it. */
val = connected ? 0 : 1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (val != ctl->forcemute) {
ctl->forcemute = val;
hdaa_audio_ctl_amp_set(ctl,
HDAA_AMP_MUTE_DEFAULT,
HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
}
} else {
/* If there is no muter - disable pin output. */
if (connected)
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
val = w->wclass.pin.ctrl |
HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
else
val = w->wclass.pin.ctrl &
~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
if (val != w->wclass.pin.ctrl) {
w->wclass.pin.ctrl = val;
hda_command(devinfo->dev,
HDA_CMD_SET_PIN_WIDGET_CTRL(0,
w->nid, w->wclass.pin.ctrl));
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/* (Un)Mute other pins. */
for (j = 0; j < 15; j++) {
if (as->pins[j] <= 0)
continue;
ctl = hdaa_audio_ctl_amp_get(devinfo,
as->pins[j], HDAA_CTL_IN, -1, 1);
if (ctl != NULL && ctl->mute) {
/* If pin has muter - use it. */
val = connected ? 1 : 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (val == ctl->forcemute)
continue;
ctl->forcemute = val;
hdaa_audio_ctl_amp_set(ctl,
HDAA_AMP_MUTE_DEFAULT,
HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
continue;
}
/* If there is no muter - disable pin output. */
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
w1 = hdaa_widget_get(devinfo, as->pins[j]);
if (w1 != NULL) {
if (connected)
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
val = w1->wclass.pin.ctrl &
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
else
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
val = w1->wclass.pin.ctrl |
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (val != w1->wclass.pin.ctrl) {
w1->wclass.pin.ctrl = val;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hda_command(devinfo->dev,
HDA_CMD_SET_PIN_WIDGET_CTRL(0,
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
w1->nid, w1->wclass.pin.ctrl));
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
}
}
/*
* Recording source change handler.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
static void
hdaa_autorecsrc_handler(struct hdaa_audio_as *as, struct hdaa_widget *w)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_pcm_devinfo *pdevinfo = as->pdevinfo;
struct hdaa_devinfo *devinfo;
struct hdaa_widget *w1;
int i, mask, fullmask, prio, bestprio;
char buf[128];
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (!as->mixed || pdevinfo == NULL || pdevinfo->mixer == NULL)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
return;
/* Don't touch anything if we asked not to. */
if (pdevinfo->autorecsrc == 0 ||
(pdevinfo->autorecsrc == 1 && w != NULL))
return;
/* Don't touch anything if "mix" or "speaker" selected. */
if (pdevinfo->recsrc & (SOUND_MASK_IMIX | SOUND_MASK_SPEAKER))
return;
/* Don't touch anything if several selected. */
if (ffs(pdevinfo->recsrc) != fls(pdevinfo->recsrc))
return;
devinfo = pdevinfo->devinfo;
mask = fullmask = 0;
bestprio = 0;
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
continue;
w1 = hdaa_widget_get(devinfo, as->pins[i]);
if (w1 == NULL || w1->enable == 0)
continue;
if (w1->wclass.pin.connected == 0)
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
continue;
prio = (w1->wclass.pin.connected == 1) ? 2 : 1;
if (prio < bestprio)
continue;
if (prio > bestprio) {
mask = 0;
bestprio = prio;
}
mask |= (1 << w1->ossdev);
fullmask |= (1 << w1->ossdev);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
if (mask == 0)
return;
/* Prefer newly connected input. */
if (w != NULL && (mask & (1 << w->ossdev)))
mask = (1 << w->ossdev);
/* Prefer previously selected input */
if (mask & pdevinfo->recsrc)
mask &= pdevinfo->recsrc;
/* Prefer mic. */
if (mask & SOUND_MASK_MIC)
mask = SOUND_MASK_MIC;
/* Prefer monitor (2nd mic). */
if (mask & SOUND_MASK_MONITOR)
mask = SOUND_MASK_MONITOR;
/* Just take first one. */
mask = (1 << (ffs(mask) - 1));
HDA_BOOTVERBOSE(
hdaa_audio_ctl_ossmixer_mask2allname(mask, buf, sizeof(buf));
device_printf(pdevinfo->dev,
"Automatically set rec source to: %s\n", buf);
);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_unlock(devinfo);
mix_setrecsrc(pdevinfo->mixer, mask);
hdaa_lock(devinfo);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
/*
* Jack presence detection event handler.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
static void
hdaa_presence_handler(struct hdaa_widget *w)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_devinfo *devinfo = w->devinfo;
struct hdaa_audio_as *as;
uint32_t res;
int connected, old;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (w->enable == 0 || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
return;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
(HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0)
return;
res = hda_command(devinfo->dev, HDA_CMD_GET_PIN_SENSE(0, w->nid));
connected = (res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) != 0;
if (devinfo->quirks & HDAA_QUIRK_SENSEINV)
connected = !connected;
old = w->wclass.pin.connected;
if (connected == old)
return;
w->wclass.pin.connected = connected;
HDA_BOOTVERBOSE(
if (connected || old != 2) {
device_printf(devinfo->dev,
"Pin sense: nid=%d sence=0x%08x (%sconnected)\n",
w->nid, res, !connected ? "dis" : "");
}
);
as = &devinfo->as[w->bindas];
if (as->hpredir >= 0 && as->pins[15] == w->nid)
hdaa_hpredir_handler(w);
if (as->dir == HDAA_CTL_IN && old != 2)
hdaa_autorecsrc_handler(as, w);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
/*
* Callback for poll based presence detection.
*/
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
static void
hdaa_jack_poll_callback(void *arg)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_devinfo *devinfo = arg;
struct hdaa_widget *w;
int i;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_lock(devinfo);
if (devinfo->poll_ival == 0) {
hdaa_unlock(devinfo);
return;
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (i = 0; i < devinfo->ascnt; i++) {
if (devinfo->as[i].hpredir < 0)
continue;
w = hdaa_widget_get(devinfo, devinfo->as[i].pins[15]);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (w == NULL || w->enable == 0 || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
hdaa_presence_handler(w);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
}
callout_reset(&devinfo->poll_jack, devinfo->poll_ival,
hdaa_jack_poll_callback, devinfo);
hdaa_unlock(devinfo);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
}
static void
hdaa_eld_dump(struct hdaa_widget *w)
{
struct hdaa_devinfo *devinfo = w->devinfo;
device_t dev = devinfo->dev;
uint8_t *sad;
int len, mnl, i, sadc, fmt;
if (w->eld == NULL || w->eld_len < 4)
return;
device_printf(dev,
"ELD nid=%d: ELD_Ver=%u Baseline_ELD_Len=%u\n",
w->nid, w->eld[0] >> 3, w->eld[2]);
if ((w->eld[0] >> 3) != 0x02)
return;
len = min(w->eld_len, (u_int)w->eld[2] * 4);
mnl = w->eld[4] & 0x1f;
device_printf(dev,
"ELD nid=%d: CEA_EDID_Ver=%u MNL=%u\n",
w->nid, w->eld[4] >> 5, mnl);
sadc = w->eld[5] >> 4;
device_printf(dev,
"ELD nid=%d: SAD_Count=%u Conn_Type=%u S_AI=%u HDCP=%u\n",
w->nid, sadc, (w->eld[5] >> 2) & 0x3,
(w->eld[5] >> 1) & 0x1, w->eld[5] & 0x1);
device_printf(dev,
"ELD nid=%d: Aud_Synch_Delay=%ums\n",
w->nid, w->eld[6] * 2);
device_printf(dev,
"ELD nid=%d: Channels=0x%b\n",
w->nid, w->eld[7],
"\020\07RLRC\06FLRC\05RC\04RLR\03FC\02LFE\01FLR");
device_printf(dev,
"ELD nid=%d: Port_ID=0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
w->nid, w->eld[8], w->eld[9], w->eld[10], w->eld[11],
w->eld[12], w->eld[13], w->eld[14], w->eld[15]);
device_printf(dev,
"ELD nid=%d: Manufacturer_Name=0x%02x%02x\n",
w->nid, w->eld[16], w->eld[17]);
device_printf(dev,
"ELD nid=%d: Product_Code=0x%02x%02x\n",
w->nid, w->eld[18], w->eld[19]);
device_printf(dev,
"ELD nid=%d: Monitor_Name_String='%.*s'\n",
w->nid, mnl, &w->eld[20]);
for (i = 0; i < sadc; i++) {
sad = &w->eld[20 + mnl + i * 3];
fmt = (sad[0] >> 3) & 0x0f;
if (fmt == HDA_HDMI_CODING_TYPE_REF_CTX) {
fmt = (sad[2] >> 3) & 0x1f;
if (fmt < 1 || fmt > 3)
fmt = 0;
else
fmt += 14;
}
device_printf(dev,
"ELD nid=%d: %s %dch freqs=0x%b",
w->nid, HDA_HDMI_CODING_TYPES[fmt], (sad[0] & 0x07) + 1,
sad[1], "\020\007192\006176\00596\00488\00348\00244\00132");
switch (fmt) {
case HDA_HDMI_CODING_TYPE_LPCM:
printf(" sizes=0x%b",
sad[2] & 0x07, "\020\00324\00220\00116");
break;
case HDA_HDMI_CODING_TYPE_AC3:
case HDA_HDMI_CODING_TYPE_MPEG1:
case HDA_HDMI_CODING_TYPE_MP3:
case HDA_HDMI_CODING_TYPE_MPEG2:
case HDA_HDMI_CODING_TYPE_AACLC:
case HDA_HDMI_CODING_TYPE_DTS:
case HDA_HDMI_CODING_TYPE_ATRAC:
printf(" max_bitrate=%d", sad[2] * 8000);
break;
case HDA_HDMI_CODING_TYPE_WMAPRO:
printf(" profile=%d", sad[2] & 0x07);
break;
}
printf("\n");
}
}
static void
hdaa_eld_handler(struct hdaa_widget *w)
{
struct hdaa_devinfo *devinfo = w->devinfo;
uint32_t res;
int i;
if (w->enable == 0 || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
return;
if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
(HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0)
return;
res = hda_command(devinfo->dev, HDA_CMD_GET_PIN_SENSE(0, w->nid));
if ((w->eld != 0) == ((res & HDA_CMD_GET_PIN_SENSE_ELD_VALID) != 0))
return;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (w->eld != NULL) {
w->eld_len = 0;
free(w->eld, M_HDAA);
w->eld = NULL;
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Pin sense: nid=%d sence=0x%08x "
"(%sconnected, ELD %svalid)\n",
w->nid, res,
(res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) ? "" : "dis",
(res & HDA_CMD_GET_PIN_SENSE_ELD_VALID) ? "" : "in");
);
if ((res & HDA_CMD_GET_PIN_SENSE_ELD_VALID) == 0)
return;
res = hda_command(devinfo->dev,
HDA_CMD_GET_HDMI_DIP_SIZE(0, w->nid, 0x08));
if (res == HDA_INVALID)
return;
w->eld_len = res & 0xff;
if (w->eld_len != 0)
w->eld = malloc(w->eld_len, M_HDAA, M_ZERO | M_NOWAIT);
if (w->eld == NULL) {
w->eld_len = 0;
return;
}
for (i = 0; i < w->eld_len; i++) {
res = hda_command(devinfo->dev,
HDA_CMD_GET_HDMI_ELDD(0, w->nid, i));
if (res & 0x80000000)
w->eld[i] = res & 0xff;
}
HDA_BOOTVERBOSE(
hdaa_eld_dump(w);
);
}
/*
* Pin sense initializer.
*/
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
static void
hdaa_sense_init(struct hdaa_devinfo *devinfo)
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
{
struct hdaa_audio_as *as;
struct hdaa_widget *w;
int i, poll = 0;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0 || w->type !=
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap)) {
if (w->unsol < 0)
w->unsol = HDAC_UNSOL_ALLOC(
device_get_parent(devinfo->dev),
devinfo->dev, w->nid);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
hda_command(devinfo->dev,
HDA_CMD_SET_UNSOLICITED_RESPONSE(0, w->nid,
HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE | w->unsol));
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
}
as = &devinfo->as[w->bindas];
if (as->hpredir >= 0 && as->pins[15] == w->nid) {
if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
(HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0) {
device_printf(devinfo->dev,
"No presence detection support at nid %d\n",
w->nid);
} else {
if (w->unsol < 0)
poll = 1;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Headphones redirection for "
"association %d nid=%d using %s.\n",
w->bindas, w->nid,
(w->unsol < 0) ? "polling" :
"unsolicited responses");
);
};
}
hdaa_presence_handler(w);
if (!HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap) &&
!HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
continue;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
hdaa_eld_handler(w);
}
if (poll) {
callout_reset(&devinfo->poll_jack, 1,
hdaa_jack_poll_callback, devinfo);
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
}
static void
hdaa_sense_deinit(struct hdaa_devinfo *devinfo)
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
{
struct hdaa_widget *w;
int i;
callout_stop(&devinfo->poll_jack);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0 || w->type !=
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (w->unsol < 0)
continue;
hda_command(devinfo->dev,
HDA_CMD_SET_UNSOLICITED_RESPONSE(0, w->nid, 0));
HDAC_UNSOL_FREE(
device_get_parent(devinfo->dev), devinfo->dev,
w->unsol);
w->unsol = -1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
uint32_t
hdaa_widget_pin_patch(uint32_t config, const char *str)
{
char buf[256];
char *key, *value, *rest, *bad;
int ival, i;
strlcpy(buf, str, sizeof(buf));
rest = buf;
while ((key = strsep(&rest, "=")) != NULL) {
value = strsep(&rest, " \t");
if (value == NULL)
break;
ival = strtol(value, &bad, 10);
if (strcmp(key, "seq") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK;
config |= ((ival << HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT) &
HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK);
} else if (strcmp(key, "as") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK;
config |= ((ival << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT) &
HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK);
} else if (strcmp(key, "misc") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_MISC_MASK;
config |= ((ival << HDA_CONFIG_DEFAULTCONF_MISC_SHIFT) &
HDA_CONFIG_DEFAULTCONF_MISC_MASK);
} else if (strcmp(key, "color") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_COLOR_MASK;
if (bad[0] == 0) {
config |= ((ival << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) &
HDA_CONFIG_DEFAULTCONF_COLOR_MASK);
};
for (i = 0; i < 16; i++) {
if (strcasecmp(HDA_COLORS[i], value) == 0) {
config |= (i << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT);
break;
}
}
} else if (strcmp(key, "ctype") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK;
if (bad[0] == 0) {
config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT) &
HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK);
}
for (i = 0; i < 16; i++) {
if (strcasecmp(HDA_CONNECTORS[i], value) == 0) {
config |= (i << HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT);
break;
}
}
} else if (strcmp(key, "device") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
if (bad[0] == 0) {
config |= ((ival << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT) &
HDA_CONFIG_DEFAULTCONF_DEVICE_MASK);
continue;
};
for (i = 0; i < 16; i++) {
if (strcasecmp(HDA_DEVS[i], value) == 0) {
config |= (i << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT);
break;
}
}
} else if (strcmp(key, "loc") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_LOCATION_MASK;
if (bad[0] == 0) {
config |= ((ival << HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT) &
HDA_CONFIG_DEFAULTCONF_LOCATION_MASK);
continue;
}
for (i = 0; i < 64; i++) {
if (strcasecmp(HDA_LOCS[i], value) == 0) {
config |= (i << HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT);
break;
}
}
} else if (strcmp(key, "conn") == 0) {
config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
if (bad[0] == 0) {
config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT) &
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
continue;
};
for (i = 0; i < 4; i++) {
if (strcasecmp(HDA_CONNS[i], value) == 0) {
config |= (i << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT);
break;
}
}
}
}
return (config);
}
uint32_t
hdaa_gpio_patch(uint32_t gpio, const char *str)
{
char buf[256];
char *key, *value, *rest;
int ikey, i;
strlcpy(buf, str, sizeof(buf));
rest = buf;
while ((key = strsep(&rest, "=")) != NULL) {
value = strsep(&rest, " \t");
if (value == NULL)
break;
ikey = strtol(key, NULL, 10);
if (ikey < 0 || ikey > 7)
continue;
for (i = 0; i < 7; i++) {
if (strcasecmp(HDA_GPIO_ACTIONS[i], value) == 0) {
gpio &= ~HDAA_GPIO_MASK(ikey);
gpio |= i << HDAA_GPIO_SHIFT(ikey);
break;
}
}
}
return (gpio);
}
static void
hdaa_local_patch_pin(struct hdaa_widget *w)
{
device_t dev = w->devinfo->dev;
const char *res = NULL;
uint32_t config, orig;
char buf[32];
config = orig = w->wclass.pin.config;
snprintf(buf, sizeof(buf), "cad%u.nid%u.config",
hda_get_codec_id(dev), w->nid);
if (resource_string_value(device_get_name(
device_get_parent(device_get_parent(dev))),
device_get_unit(device_get_parent(device_get_parent(dev))),
buf, &res) == 0) {
if (strncmp(res, "0x", 2) == 0) {
config = strtol(res + 2, NULL, 16);
} else {
config = hdaa_widget_pin_patch(config, res);
}
}
snprintf(buf, sizeof(buf), "nid%u.config", w->nid);
if (resource_string_value(device_get_name(dev), device_get_unit(dev),
buf, &res) == 0) {
if (strncmp(res, "0x", 2) == 0) {
config = strtol(res + 2, NULL, 16);
} else {
config = hdaa_widget_pin_patch(config, res);
}
}
HDA_BOOTVERBOSE(
if (config != orig)
device_printf(w->devinfo->dev,
"Patching pin config nid=%u 0x%08x -> 0x%08x\n",
w->nid, orig, config);
);
w->wclass.pin.newconf = w->wclass.pin.config = config;
}
static int
hdaa_sysctl_config(SYSCTL_HANDLER_ARGS)
{
char buf[256];
int error;
uint32_t conf;
conf = *(uint32_t *)oidp->oid_arg1;
snprintf(buf, sizeof(buf), "0x%08x as=%d seq=%d "
"device=%s conn=%s ctype=%s loc=%s color=%s misc=%d",
conf,
HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf),
HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf),
HDA_DEVS[HDA_CONFIG_DEFAULTCONF_DEVICE(conf)],
HDA_CONNS[HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf)],
HDA_CONNECTORS[HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf)],
HDA_LOCS[HDA_CONFIG_DEFAULTCONF_LOCATION(conf)],
HDA_COLORS[HDA_CONFIG_DEFAULTCONF_COLOR(conf)],
HDA_CONFIG_DEFAULTCONF_MISC(conf));
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strncmp(buf, "0x", 2) == 0)
conf = strtol(buf + 2, NULL, 16);
else
conf = hdaa_widget_pin_patch(conf, buf);
*(uint32_t *)oidp->oid_arg1 = conf;
return (0);
}
static void
hdaa_config_fetch(const char *str, uint32_t *on, uint32_t *off)
{
int i = 0, j, k, len, inv;
for (;;) {
while (str[i] != '\0' &&
(str[i] == ',' || isspace(str[i]) != 0))
i++;
if (str[i] == '\0')
return;
j = i;
while (str[j] != '\0' &&
!(str[j] == ',' || isspace(str[j]) != 0))
j++;
len = j - i;
if (len > 2 && strncmp(str + i, "no", 2) == 0)
inv = 2;
else
inv = 0;
for (k = 0; len > inv && k < HDAA_QUIRKS_TAB_LEN; k++) {
if (strncmp(str + i + inv,
hdaa_quirks_tab[k].key, len - inv) != 0)
continue;
if (len - inv != strlen(hdaa_quirks_tab[k].key))
continue;
if (inv == 0) {
*on |= hdaa_quirks_tab[k].value;
*off &= ~hdaa_quirks_tab[k].value;
} else {
*off |= hdaa_quirks_tab[k].value;
*on &= ~hdaa_quirks_tab[k].value;
}
break;
}
i = j;
}
}
static int
hdaa_sysctl_quirks(SYSCTL_HANDLER_ARGS)
{
char buf[256];
int error, n = 0, i;
uint32_t quirks, quirks_off;
quirks = *(uint32_t *)oidp->oid_arg1;
buf[0] = 0;
for (i = 0; i < HDAA_QUIRKS_TAB_LEN; i++) {
if ((quirks & hdaa_quirks_tab[i].value) != 0)
n += snprintf(buf + n, sizeof(buf) - n, "%s%s",
n != 0 ? "," : "", hdaa_quirks_tab[i].key);
}
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strncmp(buf, "0x", 2) == 0)
quirks = strtol(buf + 2, NULL, 16);
else {
quirks = 0;
hdaa_config_fetch(buf, &quirks, &quirks_off);
}
*(uint32_t *)oidp->oid_arg1 = quirks;
return (0);
}
static void
hdaa_local_patch(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
const char *res = NULL;
uint32_t quirks_on = 0, quirks_off = 0, x;
int i;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
continue;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
hdaa_local_patch_pin(w);
}
if (resource_string_value(device_get_name(devinfo->dev),
device_get_unit(devinfo->dev), "config", &res) == 0) {
if (res != NULL && strlen(res) > 0)
hdaa_config_fetch(res, &quirks_on, &quirks_off);
devinfo->quirks |= quirks_on;
devinfo->quirks &= ~quirks_off;
}
if (devinfo->newquirks == -1)
devinfo->newquirks = devinfo->quirks;
else
devinfo->quirks = devinfo->newquirks;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
"Config options: 0x%08x\n", devinfo->quirks);
);
if (resource_string_value(device_get_name(devinfo->dev),
device_get_unit(devinfo->dev), "gpio_config", &res) == 0) {
if (strncmp(res, "0x", 2) == 0) {
devinfo->gpio = strtol(res + 2, NULL, 16);
} else {
devinfo->gpio = hdaa_gpio_patch(devinfo->gpio, res);
}
}
if (devinfo->newgpio == -1)
devinfo->newgpio = devinfo->gpio;
else
devinfo->gpio = devinfo->newgpio;
if (devinfo->newgpo == -1)
devinfo->newgpo = devinfo->gpo;
else
devinfo->gpo = devinfo->newgpo;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev, "GPIO config options:");
for (i = 0; i < 7; i++) {
x = (devinfo->gpio & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
if (x != 0)
printf(" %d=%s", i, HDA_GPIO_ACTIONS[x]);
}
printf("\n");
);
}
static void
hdaa_widget_connection_parse(struct hdaa_widget *w)
{
uint32_t res;
int i, j, max, ents, entnum;
nid_t nid = w->nid;
nid_t cnid, addcnid, prevcnid;
w->nconns = 0;
res = hda_command(w->devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_CONN_LIST_LENGTH));
ents = HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(res);
if (ents < 1)
return;
entnum = HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(res) ? 2 : 4;
max = (sizeof(w->conns) / sizeof(w->conns[0])) - 1;
prevcnid = 0;
#define CONN_RMASK(e) (1 << ((32 / (e)) - 1))
#define CONN_NMASK(e) (CONN_RMASK(e) - 1)
#define CONN_RESVAL(r, e, n) ((r) >> ((32 / (e)) * (n)))
#define CONN_RANGE(r, e, n) (CONN_RESVAL(r, e, n) & CONN_RMASK(e))
#define CONN_CNID(r, e, n) (CONN_RESVAL(r, e, n) & CONN_NMASK(e))
for (i = 0; i < ents; i += entnum) {
res = hda_command(w->devinfo->dev,
HDA_CMD_GET_CONN_LIST_ENTRY(0, nid, i));
for (j = 0; j < entnum; j++) {
cnid = CONN_CNID(res, entnum, j);
if (cnid == 0) {
if (w->nconns < ents)
device_printf(w->devinfo->dev,
"WARNING: nid=%d has zero cnid "
"entnum=%d j=%d index=%d "
"entries=%d found=%d res=0x%08x\n",
nid, entnum, j, i,
ents, w->nconns, res);
else
goto getconns_out;
}
if (cnid < w->devinfo->startnode ||
cnid >= w->devinfo->endnode) {
HDA_BOOTVERBOSE(
device_printf(w->devinfo->dev,
"WARNING: nid=%d has cnid outside "
"of the AFG range j=%d "
"entnum=%d index=%d res=0x%08x\n",
nid, j, entnum, i, res);
);
}
if (CONN_RANGE(res, entnum, j) == 0)
addcnid = cnid;
else if (prevcnid == 0 || prevcnid >= cnid) {
device_printf(w->devinfo->dev,
"WARNING: Invalid child range "
"nid=%d index=%d j=%d entnum=%d "
"prevcnid=%d cnid=%d res=0x%08x\n",
nid, i, j, entnum, prevcnid,
cnid, res);
addcnid = cnid;
} else
addcnid = prevcnid + 1;
while (addcnid <= cnid) {
if (w->nconns > max) {
device_printf(w->devinfo->dev,
"Adding %d (nid=%d): "
"Max connection reached! max=%d\n",
addcnid, nid, max + 1);
goto getconns_out;
}
w->connsenable[w->nconns] = 1;
w->conns[w->nconns++] = addcnid++;
}
prevcnid = cnid;
}
}
getconns_out:
return;
}
static void
hdaa_widget_parse(struct hdaa_widget *w)
{
device_t dev = w->devinfo->dev;
uint32_t wcap, cap;
nid_t nid = w->nid;
char buf[64];
w->param.widget_cap = wcap = hda_command(dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_AUDIO_WIDGET_CAP));
w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(wcap);
hdaa_widget_connection_parse(w);
if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(wcap)) {
if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
w->param.outamp_cap =
hda_command(dev,
HDA_CMD_GET_PARAMETER(0, nid,
HDA_PARAM_OUTPUT_AMP_CAP));
else
w->param.outamp_cap =
w->devinfo->outamp_cap;
} else
w->param.outamp_cap = 0;
if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(wcap)) {
if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
w->param.inamp_cap =
hda_command(dev,
HDA_CMD_GET_PARAMETER(0, nid,
HDA_PARAM_INPUT_AMP_CAP));
else
w->param.inamp_cap =
w->devinfo->inamp_cap;
} else
w->param.inamp_cap = 0;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
if (HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(wcap)) {
cap = hda_command(dev,
HDA_CMD_GET_PARAMETER(0, nid,
HDA_PARAM_SUPP_STREAM_FORMATS));
w->param.supp_stream_formats = (cap != 0) ? cap :
w->devinfo->supp_stream_formats;
cap = hda_command(dev,
HDA_CMD_GET_PARAMETER(0, nid,
HDA_PARAM_SUPP_PCM_SIZE_RATE));
w->param.supp_pcm_size_rate = (cap != 0) ? cap :
w->devinfo->supp_pcm_size_rate;
} else {
w->param.supp_stream_formats =
w->devinfo->supp_stream_formats;
w->param.supp_pcm_size_rate =
w->devinfo->supp_pcm_size_rate;
}
if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap)) {
w->wclass.conv.stripecap = hda_command(dev,
HDA_CMD_GET_STRIPE_CONTROL(0, w->nid)) >> 20;
} else
w->wclass.conv.stripecap = 1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
} else {
w->param.supp_stream_formats = 0;
w->param.supp_pcm_size_rate = 0;
}
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
w->wclass.pin.original = w->wclass.pin.newconf =
w->wclass.pin.config = hda_command(dev,
HDA_CMD_GET_CONFIGURATION_DEFAULT(0, w->nid));
w->wclass.pin.cap = hda_command(dev,
HDA_CMD_GET_PARAMETER(0, w->nid, HDA_PARAM_PIN_CAP));
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
w->wclass.pin.ctrl = hda_command(dev,
HDA_CMD_GET_PIN_WIDGET_CTRL(0, nid));
w->wclass.pin.connected = 2;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (HDA_PARAM_PIN_CAP_EAPD_CAP(w->wclass.pin.cap)) {
w->param.eapdbtl = hda_command(dev,
HDA_CMD_GET_EAPD_BTL_ENABLE(0, nid));
w->param.eapdbtl &= 0x7;
w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
} else
w->param.eapdbtl = HDA_INVALID;
hdaa_unlock(w->devinfo);
snprintf(buf, sizeof(buf), "nid%d_config", w->nid);
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
buf, CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
&w->wclass.pin.newconf, sizeof(&w->wclass.pin.newconf),
hdaa_sysctl_config, "A", "Current pin configuration");
snprintf(buf, sizeof(buf), "nid%d_original", w->nid);
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
buf, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
&w->wclass.pin.original, sizeof(&w->wclass.pin.original),
hdaa_sysctl_config, "A", "Original pin configuration");
hdaa_lock(w->devinfo);
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
w->unsol = -1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
static void
hdaa_widget_postprocess(struct hdaa_widget *w)
{
char *typestr;
w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(w->param.widget_cap);
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
typestr = "audio output";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
typestr = "audio input";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
typestr = "audio mixer";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
typestr = "audio selector";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
typestr = "pin";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET:
typestr = "power widget";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET:
typestr = "volume widget";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
typestr = "beep widget";
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET:
typestr = "vendor widget";
break;
default:
typestr = "unknown type";
break;
}
strlcpy(w->name, typestr, sizeof(w->name));
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
uint32_t config;
const char *devstr;
int conn, color;
config = w->wclass.pin.config;
devstr = HDA_DEVS[(config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >>
HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT];
conn = (config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >>
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT;
color = (config & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >>
HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT;
strlcat(w->name, ": ", sizeof(w->name));
strlcat(w->name, devstr, sizeof(w->name));
strlcat(w->name, " (", sizeof(w->name));
if (conn == 0 && color != 0 && color != 15) {
strlcat(w->name, HDA_COLORS[color], sizeof(w->name));
strlcat(w->name, " ", sizeof(w->name));
}
strlcat(w->name, HDA_CONNS[conn], sizeof(w->name));
strlcat(w->name, ")", sizeof(w->name));
}
}
struct hdaa_widget *
hdaa_widget_get(struct hdaa_devinfo *devinfo, nid_t nid)
{
if (devinfo == NULL || devinfo->widget == NULL ||
nid < devinfo->startnode || nid >= devinfo->endnode)
return (NULL);
return (&devinfo->widget[nid - devinfo->startnode]);
}
static void
hdaa_audio_ctl_amp_set_internal(struct hdaa_devinfo *devinfo, nid_t nid,
int index, int lmute, int rmute,
int left, int right, int dir)
{
uint16_t v = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
"Setting amplifier nid=%d index=%d %s mute=%d/%d vol=%d/%d\n",
nid,index,dir ? "in" : "out",lmute,rmute,left,right);
);
if (left != right || lmute != rmute) {
v = (1 << (15 - dir)) | (1 << 13) | (index << 8) |
(lmute << 7) | left;
hda_command(devinfo->dev,
HDA_CMD_SET_AMP_GAIN_MUTE(0, nid, v));
v = (1 << (15 - dir)) | (1 << 12) | (index << 8) |
(rmute << 7) | right;
} else
v = (1 << (15 - dir)) | (3 << 12) | (index << 8) |
(lmute << 7) | left;
hda_command(devinfo->dev,
HDA_CMD_SET_AMP_GAIN_MUTE(0, nid, v));
}
static void
hdaa_audio_ctl_amp_set(struct hdaa_audio_ctl *ctl, uint32_t mute,
int left, int right)
{
nid_t nid;
int lmute, rmute;
nid = ctl->widget->nid;
/* Save new values if valid. */
if (mute != HDAA_AMP_MUTE_DEFAULT)
ctl->muted = mute;
if (left != HDAA_AMP_VOL_DEFAULT)
ctl->left = left;
if (right != HDAA_AMP_VOL_DEFAULT)
ctl->right = right;
/* Prepare effective values */
if (ctl->forcemute) {
lmute = 1;
rmute = 1;
left = 0;
right = 0;
} else {
lmute = HDAA_AMP_LEFT_MUTED(ctl->muted);
rmute = HDAA_AMP_RIGHT_MUTED(ctl->muted);
left = ctl->left;
right = ctl->right;
}
/* Apply effective values */
if (ctl->dir & HDAA_CTL_OUT)
hdaa_audio_ctl_amp_set_internal(ctl->widget->devinfo, nid, ctl->index,
lmute, rmute, left, right, 0);
if (ctl->dir & HDAA_CTL_IN)
hdaa_audio_ctl_amp_set_internal(ctl->widget->devinfo, nid, ctl->index,
lmute, rmute, left, right, 1);
}
static void
hdaa_widget_connection_select(struct hdaa_widget *w, uint8_t index)
{
if (w == NULL || w->nconns < 1 || index > (w->nconns - 1))
return;
HDA_BOOTHVERBOSE(
device_printf(w->devinfo->dev,
"Setting selector nid=%d index=%d\n", w->nid, index);
);
hda_command(w->devinfo->dev,
HDA_CMD_SET_CONNECTION_SELECT_CONTROL(0, w->nid, index));
w->selconn = index;
}
/****************************************************************************
* Device Methods
****************************************************************************/
static void *
hdaa_channel_init(kobj_t obj, void *data, struct snd_dbuf *b,
struct pcm_channel *c, int dir)
{
struct hdaa_chan *ch = data;
struct hdaa_pcm_devinfo *pdevinfo = ch->pdevinfo;
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
hdaa_lock(devinfo);
if (devinfo->quirks & HDAA_QUIRK_FIXEDRATE) {
ch->caps.minspeed = ch->caps.maxspeed = 48000;
ch->pcmrates[0] = 48000;
ch->pcmrates[1] = 0;
}
ch->dir = dir;
ch->b = b;
ch->c = c;
ch->blksz = pdevinfo->chan_size / pdevinfo->chan_blkcnt;
ch->blkcnt = pdevinfo->chan_blkcnt;
hdaa_unlock(devinfo);
if (sndbuf_alloc(ch->b, bus_get_dma_tag(devinfo->dev),
hda_get_dma_nocache(devinfo->dev) ? BUS_DMA_NOCACHE : 0,
pdevinfo->chan_size) != 0)
return (NULL);
return (ch);
}
static int
hdaa_channel_setformat(kobj_t obj, void *data, uint32_t format)
{
struct hdaa_chan *ch = data;
int i;
for (i = 0; ch->caps.fmtlist[i] != 0; i++) {
if (format == ch->caps.fmtlist[i]) {
ch->fmt = format;
return (0);
}
}
return (EINVAL);
}
static uint32_t
hdaa_channel_setspeed(kobj_t obj, void *data, uint32_t speed)
{
struct hdaa_chan *ch = data;
uint32_t spd = 0, threshold;
int i;
/* First look for equal or multiple frequency. */
for (i = 0; ch->pcmrates[i] != 0; i++) {
spd = ch->pcmrates[i];
if (speed != 0 && spd / speed * speed == spd) {
ch->spd = spd;
return (spd);
}
}
/* If no match, just find nearest. */
for (i = 0; ch->pcmrates[i] != 0; i++) {
spd = ch->pcmrates[i];
threshold = spd + ((ch->pcmrates[i + 1] != 0) ?
((ch->pcmrates[i + 1] - spd) >> 1) : 0);
if (speed < threshold)
break;
}
ch->spd = spd;
return (spd);
}
static uint16_t
hdaa_stream_format(struct hdaa_chan *ch)
{
int i;
uint16_t fmt;
fmt = 0;
if (ch->fmt & AFMT_S16_LE)
fmt |= ch->bit16 << 4;
else if (ch->fmt & AFMT_S32_LE)
fmt |= ch->bit32 << 4;
else
fmt |= 1 << 4;
for (i = 0; i < HDA_RATE_TAB_LEN; i++) {
if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) {
fmt |= hda_rate_tab[i].base;
fmt |= hda_rate_tab[i].mul;
fmt |= hda_rate_tab[i].div;
break;
}
}
fmt |= (AFMT_CHANNEL(ch->fmt) - 1);
return (fmt);
}
static int
hdaa_allowed_stripes(uint16_t fmt)
{
static const int bits[8] = { 8, 16, 20, 24, 32, 32, 32, 32 };
int size;
size = bits[(fmt >> 4) & 0x03];
size *= (fmt & 0x0f) + 1;
size *= ((fmt >> 11) & 0x07) + 1;
return (0xffffffffU >> (32 - fls(size / 8)));
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
static void
hdaa_audio_setup(struct hdaa_chan *ch)
{
struct hdaa_audio_as *as = &ch->devinfo->as[ch->as];
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
struct hdaa_widget *w, *wp;
int i, j, k, chn, cchn, totalchn, totalextchn, c;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
uint16_t fmt, dfmt;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
/* Mapping channel pairs to codec pins/converters. */
const static uint16_t convmap[2][5] =
{{ 0x0010, 0x0001, 0x0201, 0x0231, 0x0231 }, /* 5.1 */
{ 0x0010, 0x0001, 0x2001, 0x2031, 0x2431 }};/* 7.1 */
/* Mapping formats to HDMI channel allocations. */
const static uint8_t hdmica[2][8] =
{{ 0x02, 0x00, 0x04, 0x08, 0x0a, 0x0e, 0x12, 0x12 }, /* x.0 */
{ 0x01, 0x03, 0x01, 0x03, 0x09, 0x0b, 0x0f, 0x13 }}; /* x.1 */
/* Mapping formats to HDMI channels order. */
const static uint32_t hdmich[2][8] =
{{ 0xFFFF0F00, 0xFFFFFF10, 0xFFF2FF10, 0xFF32FF10,
0xFF324F10, 0xF5324F10, 0x54326F10, 0x54326F10 }, /* x.0 */
{ 0xFFFFF000, 0xFFFF0100, 0xFFFFF210, 0xFFFF2310,
0xFF32F410, 0xFF324510, 0xF6324510, 0x76325410 }}; /* x.1 */
int convmapid = -1;
nid_t nid;
uint8_t csum;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
totalchn = AFMT_CHANNEL(ch->fmt);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
totalextchn = AFMT_EXTCHANNEL(ch->fmt);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
HDA_BOOTHVERBOSE(
device_printf(ch->pdevinfo->dev,
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
"PCMDIR_%s: Stream setup fmt=%08x (%d.%d) speed=%d\n",
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
(ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
ch->fmt, totalchn - totalextchn, totalextchn, ch->spd);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
);
fmt = hdaa_stream_format(ch);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
/* Set channels to I/O converters mapping for known speaker setups. */
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if ((as->pinset == 0x0007 || as->pinset == 0x0013)) /* Standard 5.1 */
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
convmapid = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
else if (as->pinset == 0x0017) /* Standard 7.1 */
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
convmapid = 1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
dfmt = HDA_CMD_SET_DIGITAL_CONV_FMT1_DIGEN;
if (ch->fmt & AFMT_AC3)
dfmt |= HDA_CMD_SET_DIGITAL_CONV_FMT1_NAUDIO;
chn = 0;
for (i = 0; ch->io[i] != -1; i++) {
w = hdaa_widget_get(ch->devinfo, ch->io[i]);
if (w == NULL)
continue;
/* If HP redirection is enabled, but failed to use same
DAC, make last DAC to duplicate first one. */
if (as->fakeredir && i == (as->pincnt - 1)) {
c = (ch->sid << 4);
} else {
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
/* Map channels to I/O converters, if set. */
if (convmapid >= 0)
chn = (((convmap[convmapid][totalchn / 2]
>> i * 4) & 0xf) - 1) * 2;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (chn < 0 || chn >= totalchn) {
c = 0;
} else {
c = (ch->sid << 4) | chn;
}
}
hda_command(ch->devinfo->dev,
HDA_CMD_SET_CONV_FMT(0, ch->io[i], fmt));
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
hda_command(ch->devinfo->dev,
HDA_CMD_SET_DIGITAL_CONV_FMT1(0, ch->io[i], dfmt));
}
hda_command(ch->devinfo->dev,
HDA_CMD_SET_CONV_STREAM_CHAN(0, ch->io[i], c));
if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap)) {
hda_command(ch->devinfo->dev,
HDA_CMD_SET_STRIPE_CONTROL(0, w->nid, ch->stripectl));
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
cchn = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
if (cchn > 1 && chn < totalchn) {
cchn = min(cchn, totalchn - chn - 1);
hda_command(ch->devinfo->dev,
HDA_CMD_SET_CONV_CHAN_COUNT(0, ch->io[i], cchn));
}
HDA_BOOTHVERBOSE(
device_printf(ch->pdevinfo->dev,
"PCMDIR_%s: Stream setup nid=%d: "
"fmt=0x%04x, dfmt=0x%04x, chan=0x%04x, "
"chan_count=0x%02x, stripe=%d\n",
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
(ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
ch->io[i], fmt, dfmt, c, cchn, ch->stripectl);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
);
for (j = 0; j < 16; j++) {
if (as->dacs[ch->asindex][j] != ch->io[i])
continue;
nid = as->pins[j];
wp = hdaa_widget_get(ch->devinfo, nid);
if (wp == NULL)
continue;
if (!HDA_PARAM_PIN_CAP_DP(wp->wclass.pin.cap) &&
!HDA_PARAM_PIN_CAP_HDMI(wp->wclass.pin.cap))
continue;
/* Set channel mapping. */
for (k = 0; k < 8; k++) {
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_CHAN_SLOT(0, nid,
(((hdmich[totalextchn == 0 ? 0 : 1][totalchn - 1]
>> (k * 4)) & 0xf) << 4) | k));
}
/*
* Enable High Bit Rate (HBR) Encoded Packet Type
* (EPT), if supported and needed (8ch data).
*/
if (HDA_PARAM_PIN_CAP_HDMI(wp->wclass.pin.cap) &&
HDA_PARAM_PIN_CAP_HBR(wp->wclass.pin.cap)) {
wp->wclass.pin.ctrl &=
~HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK;
if ((ch->fmt & AFMT_AC3) && (cchn == 7))
wp->wclass.pin.ctrl |= 0x03;
hda_command(ch->devinfo->dev,
HDA_CMD_SET_PIN_WIDGET_CTRL(0, nid,
wp->wclass.pin.ctrl));
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
/* Stop audio infoframe transmission. */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_INDEX(0, nid, 0x00));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_XMIT(0, nid, 0x00));
/* Clear audio infoframe buffer. */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_INDEX(0, nid, 0x00));
for (k = 0; k < 32; k++)
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x00));
/* Write HDMI/DisplayPort audio infoframe. */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_INDEX(0, nid, 0x00));
if (w->eld != NULL && w->eld_len >= 6 &&
((w->eld[5] >> 2) & 0x3) == 1) { /* DisplayPort */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x84));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x1b));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x44));
} else { /* HDMI */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x84));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x01));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x0a));
csum = 0;
csum -= 0x84 + 0x01 + 0x0a + (totalchn - 1) +
hdmica[totalextchn == 0 ? 0 : 1][totalchn - 1];
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, csum));
}
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, totalchn - 1));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x00));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid, 0x00));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_DATA(0, nid,
hdmica[totalextchn == 0 ? 0 : 1][totalchn - 1]));
/* Start audio infoframe transmission. */
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_INDEX(0, nid, 0x00));
hda_command(ch->devinfo->dev,
HDA_CMD_SET_HDMI_DIP_XMIT(0, nid, 0xc0));
}
chn += cchn + 1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/*
* Greatest Common Divisor.
*/
static unsigned
gcd(unsigned a, unsigned b)
{
u_int c;
while (b != 0) {
c = a;
a = b;
b = (c % b);
}
return (a);
}
/*
* Least Common Multiple.
*/
static unsigned
lcm(unsigned a, unsigned b)
{
return ((a * b) / gcd(a, b));
}
static int
hdaa_channel_setfragments(kobj_t obj, void *data,
uint32_t blksz, uint32_t blkcnt)
{
struct hdaa_chan *ch = data;
blksz -= blksz % lcm(HDA_DMA_ALIGNMENT, sndbuf_getalign(ch->b));
if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN))
blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN;
if (blksz < HDA_BLK_MIN)
blksz = HDA_BLK_MIN;
if (blkcnt > HDA_BDL_MAX)
blkcnt = HDA_BDL_MAX;
if (blkcnt < HDA_BDL_MIN)
blkcnt = HDA_BDL_MIN;
while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) {
if ((blkcnt >> 1) >= HDA_BDL_MIN)
blkcnt >>= 1;
else if ((blksz >> 1) >= HDA_BLK_MIN)
blksz >>= 1;
else
break;
}
if ((sndbuf_getblksz(ch->b) != blksz ||
sndbuf_getblkcnt(ch->b) != blkcnt) &&
sndbuf_resize(ch->b, blkcnt, blksz) != 0)
device_printf(ch->devinfo->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, blkcnt);
ch->blksz = sndbuf_getblksz(ch->b);
ch->blkcnt = sndbuf_getblkcnt(ch->b);
return (0);
}
static uint32_t
hdaa_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz)
{
struct hdaa_chan *ch = data;
hdaa_channel_setfragments(obj, data, blksz, ch->pdevinfo->chan_blkcnt);
return (ch->blksz);
}
static void
hdaa_channel_stop(struct hdaa_chan *ch)
{
struct hdaa_devinfo *devinfo = ch->devinfo;
struct hdaa_widget *w;
int i;
if ((ch->flags & HDAA_CHN_RUNNING) == 0)
return;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->flags &= ~HDAA_CHN_RUNNING;
HDAC_STREAM_STOP(device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
for (i = 0; ch->io[i] != -1; i++) {
w = hdaa_widget_get(ch->devinfo, ch->io[i]);
if (w == NULL)
continue;
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
hda_command(devinfo->dev,
HDA_CMD_SET_DIGITAL_CONV_FMT1(0, ch->io[i], 0));
}
hda_command(devinfo->dev,
HDA_CMD_SET_CONV_STREAM_CHAN(0, ch->io[i],
0));
}
HDAC_STREAM_FREE(device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
}
static int
hdaa_channel_start(struct hdaa_chan *ch)
{
struct hdaa_devinfo *devinfo = ch->devinfo;
uint32_t fmt;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
fmt = hdaa_stream_format(ch);
ch->stripectl = fls(ch->stripecap & hdaa_allowed_stripes(fmt)) - 1;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->sid = HDAC_STREAM_ALLOC(device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, fmt, ch->stripectl, &ch->dmapos);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (ch->sid <= 0)
return (EBUSY);
hdaa_audio_setup(ch);
HDAC_STREAM_RESET(device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
HDAC_STREAM_START(device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid,
sndbuf_getbufaddr(ch->b), ch->blksz, ch->blkcnt);
ch->flags |= HDAA_CHN_RUNNING;
return (0);
}
static int
hdaa_channel_trigger(kobj_t obj, void *data, int go)
{
struct hdaa_chan *ch = data;
int error = 0;
if (!PCMTRIG_COMMON(go))
return (0);
hdaa_lock(ch->devinfo);
switch (go) {
case PCMTRIG_START:
error = hdaa_channel_start(ch);
break;
case PCMTRIG_STOP:
case PCMTRIG_ABORT:
hdaa_channel_stop(ch);
break;
default:
break;
}
hdaa_unlock(ch->devinfo);
return (error);
}
static uint32_t
hdaa_channel_getptr(kobj_t obj, void *data)
{
struct hdaa_chan *ch = data;
struct hdaa_devinfo *devinfo = ch->devinfo;
uint32_t ptr;
hdaa_lock(devinfo);
if (ch->dmapos != NULL) {
ptr = *(ch->dmapos);
} else {
ptr = HDAC_STREAM_GETPTR(
device_get_parent(devinfo->dev), devinfo->dev,
ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
}
hdaa_unlock(devinfo);
/*
* Round to available space and force 128 bytes aligment.
*/
ptr %= ch->blksz * ch->blkcnt;
ptr &= HDA_BLK_ALIGN;
return (ptr);
}
static struct pcmchan_caps *
hdaa_channel_getcaps(kobj_t obj, void *data)
{
return (&((struct hdaa_chan *)data)->caps);
}
static kobj_method_t hdaa_channel_methods[] = {
KOBJMETHOD(channel_init, hdaa_channel_init),
KOBJMETHOD(channel_setformat, hdaa_channel_setformat),
KOBJMETHOD(channel_setspeed, hdaa_channel_setspeed),
KOBJMETHOD(channel_setblocksize, hdaa_channel_setblocksize),
KOBJMETHOD(channel_setfragments, hdaa_channel_setfragments),
KOBJMETHOD(channel_trigger, hdaa_channel_trigger),
KOBJMETHOD(channel_getptr, hdaa_channel_getptr),
KOBJMETHOD(channel_getcaps, hdaa_channel_getcaps),
KOBJMETHOD_END
};
CHANNEL_DECLARE(hdaa_channel);
static int
hdaa_audio_ctl_ossmixer_init(struct snd_mixer *m)
{
struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w, *cw;
uint32_t mask, recmask;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int i, j;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_lock(devinfo);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
pdevinfo->mixer = m;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Make sure that in case of soft volume it won't stay muted. */
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
pdevinfo->left[i] = 100;
pdevinfo->right[i] = 100;
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* Declare volume controls assigned to this association. */
mask = pdevinfo->ossmask;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (pdevinfo->playas >= 0) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* Declate EAPD as ogain control. */
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
w->param.eapdbtl == HDA_INVALID ||
w->bindas != pdevinfo->playas)
continue;
mask |= SOUND_MASK_OGAIN;
break;
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* Declare soft PCM volume if needed. */
if ((mask & SOUND_MASK_PCM) == 0 ||
(devinfo->quirks & HDAA_QUIRK_SOFTPCMVOL) ||
pdevinfo->minamp[SOUND_MIXER_PCM] ==
pdevinfo->maxamp[SOUND_MIXER_PCM]) {
mask |= SOUND_MASK_PCM;
pcm_setflags(pdevinfo->dev, pcm_getflags(pdevinfo->dev) | SD_F_SOFTPCMVOL);
HDA_BOOTHVERBOSE(
device_printf(pdevinfo->dev,
"Forcing Soft PCM volume\n");
);
}
/* Declare master volume if needed. */
if ((mask & SOUND_MASK_VOLUME) == 0) {
mask |= SOUND_MASK_VOLUME;
mix_setparentchild(m, SOUND_MIXER_VOLUME,
SOUND_MASK_PCM);
mix_setrealdev(m, SOUND_MIXER_VOLUME,
SOUND_MIXER_NONE);
HDA_BOOTHVERBOSE(
device_printf(pdevinfo->dev,
"Forcing master volume with PCM\n");
);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
/* Declare record sources available to this association. */
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
recmask = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (pdevinfo->recas >= 0) {
for (i = 0; i < 16; i++) {
if (devinfo->as[pdevinfo->recas].dacs[0][i] < 0)
continue;
w = hdaa_widget_get(devinfo,
devinfo->as[pdevinfo->recas].dacs[0][i]);
if (w == NULL || w->enable == 0)
continue;
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j] == 0)
continue;
cw = hdaa_widget_get(devinfo, w->conns[j]);
if (cw == NULL || cw->enable == 0)
continue;
if (cw->bindas != pdevinfo->recas &&
cw->bindas != -2)
continue;
recmask |= cw->ossmask;
}
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
recmask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
mask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
pdevinfo->ossmask = mask;
mix_setrecdevs(m, recmask);
mix_setdevs(m, mask);
hdaa_unlock(devinfo);
return (0);
}
/*
* Update amplification per pdevinfo per ossdev, calculate summary coefficient
* and write it to codec, update *left and *right to reflect remaining error.
*/
static void
hdaa_audio_ctl_dev_set(struct hdaa_audio_ctl *ctl, int ossdev,
int mute, int *left, int *right)
{
int i, zleft, zright, sleft, sright, smute, lval, rval;
ctl->devleft[ossdev] = *left;
ctl->devright[ossdev] = *right;
ctl->devmute[ossdev] = mute;
smute = sleft = sright = zleft = zright = 0;
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
sleft += ctl->devleft[i];
sright += ctl->devright[i];
smute |= ctl->devmute[i];
if (i == ossdev)
continue;
zleft += ctl->devleft[i];
zright += ctl->devright[i];
}
lval = QDB2VAL(ctl, sleft);
rval = QDB2VAL(ctl, sright);
hdaa_audio_ctl_amp_set(ctl, smute, lval, rval);
*left -= VAL2QDB(ctl, lval) - VAL2QDB(ctl, QDB2VAL(ctl, zleft));
*right -= VAL2QDB(ctl, rval) - VAL2QDB(ctl, QDB2VAL(ctl, zright));
}
/*
* Trace signal from source, setting volumes on the way.
*/
static void
hdaa_audio_ctl_source_volume(struct hdaa_pcm_devinfo *pdevinfo,
int ossdev, nid_t nid, int index, int mute, int left, int right, int depth)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w, *wc;
struct hdaa_audio_ctl *ctl;
int i, j, conns = 0;
if (depth > HDA_PARSE_MAXDEPTH)
return;
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return;
/* Count number of active inputs. */
if (depth > 0) {
for (j = 0; j < w->nconns; j++) {
if (!w->connsenable[j])
continue;
conns++;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* If this is not a first step - use input mixer.
Pins have common input ctl so care must be taken. */
if (depth > 0 && (conns == 1 ||
w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)) {
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_IN,
index, 1);
if (ctl)
hdaa_audio_ctl_dev_set(ctl, ossdev, mute, &left, &right);
}
/* If widget has own ossdev - not traverse it.
It will be traversed on it's own. */
if (w->ossdev >= 0 && depth > 0)
return;
/* We must not traverse pin */
if ((w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) &&
depth > 0)
return;
/*
* If signals mixed, we can't assign controls farther.
* Ignore this on depth zero. Caller must knows why.
*/
if (conns > 1 &&
(w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER ||
w->selconn != index))
return;
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_OUT, -1, 1);
if (ctl)
hdaa_audio_ctl_dev_set(ctl, ossdev, mute, &left, &right);
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
wc = hdaa_widget_get(devinfo, i);
if (wc == NULL || wc->enable == 0)
continue;
for (j = 0; j < wc->nconns; j++) {
if (wc->connsenable[j] && wc->conns[j] == nid) {
hdaa_audio_ctl_source_volume(pdevinfo, ossdev,
wc->nid, j, mute, left, right, depth + 1);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return;
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* Trace signal from destination, setting volumes on the way.
*/
static void
hdaa_audio_ctl_dest_volume(struct hdaa_pcm_devinfo *pdevinfo,
int ossdev, nid_t nid, int index, int mute, int left, int right, int depth)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w, *wc;
struct hdaa_audio_ctl *ctl;
int i, j, consumers, cleft, cright;
if (depth > HDA_PARSE_MAXDEPTH)
return;
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return;
if (depth > 0) {
/* If this node produce output for several consumers,
we can't touch it. */
consumers = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
wc = hdaa_widget_get(devinfo, i);
if (wc == NULL || wc->enable == 0)
continue;
for (j = 0; j < wc->nconns; j++) {
if (wc->connsenable[j] && wc->conns[j] == nid)
consumers++;
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* The only exception is if real HP redirection is configured
and this is a duplication point.
XXX: Actually exception is not completely correct.
XXX: Duplication point check is not perfect. */
if ((consumers == 2 && (w->bindas < 0 ||
as[w->bindas].hpredir < 0 || as[w->bindas].fakeredir ||
(w->bindseqmask & (1 << 15)) == 0)) ||
consumers > 2)
return;
/* Else use it's output mixer. */
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_OUT, -1, 1);
if (ctl)
hdaa_audio_ctl_dev_set(ctl, ossdev, mute, &left, &right);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* We must not traverse pin */
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
depth > 0)
return;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
for (i = 0; i < w->nconns; i++) {
if (w->connsenable[i] == 0)
continue;
if (index >= 0 && i != index)
continue;
cleft = left;
cright = right;
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_IN, i, 1);
if (ctl)
hdaa_audio_ctl_dev_set(ctl, ossdev, mute, &cleft, &cright);
hdaa_audio_ctl_dest_volume(pdevinfo, ossdev, w->conns[i], -1,
mute, cleft, cright, depth + 1);
}
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* Set volumes for the specified pdevinfo and ossdev.
*/
static void
hdaa_audio_ctl_dev_volume(struct hdaa_pcm_devinfo *pdevinfo, unsigned dev)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w, *cw;
uint32_t mute;
int lvol, rvol;
int i, j;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
mute = 0;
if (pdevinfo->left[dev] == 0) {
mute |= HDAA_AMP_MUTE_LEFT;
lvol = -4000;
} else
lvol = ((pdevinfo->maxamp[dev] - pdevinfo->minamp[dev]) *
pdevinfo->left[dev] + 50) / 100 + pdevinfo->minamp[dev];
if (pdevinfo->right[dev] == 0) {
mute |= HDAA_AMP_MUTE_RIGHT;
rvol = -4000;
} else
rvol = ((pdevinfo->maxamp[dev] - pdevinfo->minamp[dev]) *
pdevinfo->right[dev] + 50) / 100 + pdevinfo->minamp[dev];
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->bindas < 0) {
if (pdevinfo->index != 0)
continue;
} else {
if (w->bindas != pdevinfo->playas &&
w->bindas != pdevinfo->recas)
continue;
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (dev == SOUND_MIXER_RECLEV &&
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
hdaa_audio_ctl_dest_volume(pdevinfo, dev,
w->nid, -1, mute, lvol, rvol, 0);
continue;
}
if (dev == SOUND_MIXER_VOLUME &&
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
devinfo->as[w->bindas].dir == HDAA_CTL_OUT) {
hdaa_audio_ctl_dest_volume(pdevinfo, dev,
w->nid, -1, mute, lvol, rvol, 0);
continue;
}
if (dev == SOUND_MIXER_IGAIN &&
w->pflags & HDAA_ADC_MONITOR) {
for (j = 0; j < w->nconns; j++) {
if (!w->connsenable[j])
continue;
cw = hdaa_widget_get(devinfo, w->conns[j]);
if (cw == NULL || cw->enable == 0)
continue;
if (cw->bindas == -1)
continue;
if (cw->bindas >= 0 &&
devinfo->as[cw->bindas].dir != HDAA_CTL_IN)
continue;
hdaa_audio_ctl_dest_volume(pdevinfo, dev,
w->nid, j, mute, lvol, rvol, 0);
}
continue;
}
if (w->ossdev != dev)
continue;
hdaa_audio_ctl_source_volume(pdevinfo, dev,
w->nid, -1, mute, lvol, rvol, 0);
if (dev == SOUND_MIXER_IMIX && (w->pflags & HDAA_IMIX_AS_DST))
hdaa_audio_ctl_dest_volume(pdevinfo, dev,
w->nid, -1, mute, lvol, rvol, 0);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* OSS Mixer set method.
*/
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
static int
hdaa_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev,
unsigned left, unsigned right)
{
struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int i;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_lock(devinfo);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Save new values. */
pdevinfo->left[dev] = left;
pdevinfo->right[dev] = right;
/* 'ogain' is the special case implemented with EAPD. */
if (dev == SOUND_MIXER_OGAIN) {
uint32_t orig;
w = NULL;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
w->param.eapdbtl == HDA_INVALID)
continue;
break;
}
if (i >= devinfo->endnode) {
hdaa_unlock(devinfo);
return (-1);
}
orig = w->param.eapdbtl;
if (left == 0)
w->param.eapdbtl &= ~HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
else
w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
if (orig != w->param.eapdbtl) {
uint32_t val;
val = w->param.eapdbtl;
if (devinfo->quirks & HDAA_QUIRK_EAPDINV)
val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
hda_command(devinfo->dev,
HDA_CMD_SET_EAPD_BTL_ENABLE(0, w->nid, val));
}
hdaa_unlock(devinfo);
return (left | (left << 8));
}
/* Recalculate all controls related to this OSS device. */
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
hdaa_audio_ctl_dev_volume(pdevinfo, dev);
hdaa_unlock(devinfo);
return (left | (right << 8));
}
/*
* Set mixer settings to our own default values:
* +20dB for mics, -10dB for analog vol, mute for igain, 0dB for others.
*/
static void
hdaa_audio_ctl_set_defaults(struct hdaa_pcm_devinfo *pdevinfo)
{
int amp, vol, dev;
for (dev = 0; dev < SOUND_MIXER_NRDEVICES; dev++) {
if ((pdevinfo->ossmask & (1 << dev)) == 0)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/* If the value was overriden, leave it as is. */
if (resource_int_value(device_get_name(pdevinfo->dev),
device_get_unit(pdevinfo->dev), ossnames[dev], &vol) == 0)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
vol = -1;
if (dev == SOUND_MIXER_OGAIN)
vol = 100;
else if (dev == SOUND_MIXER_IGAIN)
vol = 0;
else if (dev == SOUND_MIXER_MIC ||
dev == SOUND_MIXER_MONITOR)
amp = 20 * 4; /* +20dB */
else if (dev == SOUND_MIXER_VOLUME && !pdevinfo->digital)
amp = -10 * 4; /* -10dB */
else
amp = 0;
if (vol < 0 &&
(pdevinfo->maxamp[dev] - pdevinfo->minamp[dev]) <= 0) {
vol = 100;
} else if (vol < 0) {
vol = ((amp - pdevinfo->minamp[dev]) * 100 +
(pdevinfo->maxamp[dev] - pdevinfo->minamp[dev]) / 2) /
(pdevinfo->maxamp[dev] - pdevinfo->minamp[dev]);
vol = imin(imax(vol, 1), 100);
}
mix_set(pdevinfo->mixer, dev, vol, vol);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/*
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
* Recursively commutate specified record source.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
static uint32_t
hdaa_audio_ctl_recsel_comm(struct hdaa_pcm_devinfo *pdevinfo, uint32_t src, nid_t nid, int depth)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w, *cw;
struct hdaa_audio_ctl *ctl;
char buf[64];
int i, muted;
uint32_t res = 0;
if (depth > HDA_PARSE_MAXDEPTH)
return (0);
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return (0);
for (i = 0; i < w->nconns; i++) {
if (w->connsenable[i] == 0)
continue;
cw = hdaa_widget_get(devinfo, w->conns[i]);
if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
continue;
/* Call recursively to trace signal to it's source if needed. */
if ((src & cw->ossmask) != 0) {
if (cw->ossdev < 0) {
res |= hdaa_audio_ctl_recsel_comm(pdevinfo, src,
w->conns[i], depth + 1);
} else {
res |= cw->ossmask;
}
}
/* We have two special cases: mixers and others (selectors). */
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) {
ctl = hdaa_audio_ctl_amp_get(devinfo,
w->nid, HDAA_CTL_IN, i, 1);
if (ctl == NULL)
continue;
/* If we have input control on this node mute them
* according to requested sources. */
muted = (src & cw->ossmask) ? 0 : 1;
if (muted != ctl->forcemute) {
ctl->forcemute = muted;
hdaa_audio_ctl_amp_set(ctl,
HDAA_AMP_MUTE_DEFAULT,
HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
}
HDA_BOOTHVERBOSE(
device_printf(pdevinfo->dev,
"Recsel (%s): nid %d source %d %s\n",
hdaa_audio_ctl_ossmixer_mask2allname(
src, buf, sizeof(buf)),
nid, i, muted?"mute":"unmute");
);
} else {
if (w->nconns == 1)
break;
if ((src & cw->ossmask) == 0)
continue;
/* If we found requested source - select it and exit. */
hdaa_widget_connection_select(w, i);
HDA_BOOTHVERBOSE(
device_printf(pdevinfo->dev,
"Recsel (%s): nid %d source %d select\n",
hdaa_audio_ctl_ossmixer_mask2allname(
src, buf, sizeof(buf)),
nid, i);
);
break;
}
}
return (res);
}
static uint32_t
hdaa_audio_ctl_ossmixer_setrecsrc(struct snd_mixer *m, uint32_t src)
{
struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w;
struct hdaa_audio_as *as;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
struct hdaa_audio_ctl *ctl;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
struct hdaa_chan *ch;
int i, j;
uint32_t ret = 0xffffffff;
hdaa_lock(devinfo);
if (pdevinfo->recas < 0) {
hdaa_unlock(devinfo);
return (0);
}
as = &devinfo->as[pdevinfo->recas];
/* For non-mixed associations we always recording everything. */
if (!as->mixed) {
hdaa_unlock(devinfo);
return (mix_getrecdevs(m));
}
/* Commutate requested recsrc for each ADC. */
for (j = 0; j < as->num_chans; j++) {
ch = &devinfo->chans[as->chans[j]];
for (i = 0; ch->io[i] >= 0; i++) {
w = hdaa_widget_get(devinfo, ch->io[i]);
if (w == NULL || w->enable == 0)
continue;
ret &= hdaa_audio_ctl_recsel_comm(pdevinfo, src,
ch->io[i], 0);
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (ret == 0xffffffff)
ret = 0;
/*
* Some controls could be shared. Reset volumes for controls
* related to previously chosen devices, as they may no longer
* affect the signal.
*/
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0 ||
!(ctl->ossmask & pdevinfo->recsrc))
continue;
if (!((pdevinfo->playas >= 0 &&
ctl->widget->bindas == pdevinfo->playas) ||
(pdevinfo->recas >= 0 &&
ctl->widget->bindas == pdevinfo->recas) ||
(pdevinfo->index == 0 &&
ctl->widget->bindas == -2)))
continue;
for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
if (pdevinfo->recsrc & (1 << j)) {
ctl->devleft[j] = 0;
ctl->devright[j] = 0;
ctl->devmute[j] = 0;
}
}
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* Some controls could be shared. Set volumes for controls
* related to devices selected both previously and now.
*/
for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
if ((ret | pdevinfo->recsrc) & (1 << j))
hdaa_audio_ctl_dev_volume(pdevinfo, j);
}
pdevinfo->recsrc = ret;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_unlock(devinfo);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (ret);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
static kobj_method_t hdaa_audio_ctl_ossmixer_methods[] = {
KOBJMETHOD(mixer_init, hdaa_audio_ctl_ossmixer_init),
KOBJMETHOD(mixer_set, hdaa_audio_ctl_ossmixer_set),
KOBJMETHOD(mixer_setrecsrc, hdaa_audio_ctl_ossmixer_setrecsrc),
KOBJMETHOD_END
};
MIXER_DECLARE(hdaa_audio_ctl_ossmixer);
static void
hdaa_dump_gpi(struct hdaa_devinfo *devinfo)
{
device_t dev = devinfo->dev;
int i;
uint32_t data, wake, unsol, sticky;
if (HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap) > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPI_DATA(0, devinfo->nid));
wake = hda_command(dev,
HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(0, devinfo->nid));
unsol = hda_command(dev,
HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(0, devinfo->nid));
sticky = hda_command(dev,
HDA_CMD_GET_GPI_STICKY_MASK(0, devinfo->nid));
for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap); i++) {
device_printf(dev, " GPI%d:%s%s%s state=%d", i,
(sticky & (1 << i)) ? " sticky" : "",
(unsol & (1 << i)) ? " unsol" : "",
(wake & (1 << i)) ? " wake" : "",
(data >> i) & 1);
}
}
}
static void
hdaa_dump_gpio(struct hdaa_devinfo *devinfo)
{
device_t dev = devinfo->dev;
int i;
uint32_t data, dir, enable, wake, unsol, sticky;
if (HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap) > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
enable = hda_command(dev,
HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
dir = hda_command(dev,
HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
wake = hda_command(dev,
HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(0, devinfo->nid));
unsol = hda_command(dev,
HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(0, devinfo->nid));
sticky = hda_command(dev,
HDA_CMD_GET_GPIO_STICKY_MASK(0, devinfo->nid));
for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap); i++) {
device_printf(dev, " GPIO%d: ", i);
if ((enable & (1 << i)) == 0) {
printf("disabled\n");
continue;
}
if ((dir & (1 << i)) == 0) {
printf("input%s%s%s",
(sticky & (1 << i)) ? " sticky" : "",
(unsol & (1 << i)) ? " unsol" : "",
(wake & (1 << i)) ? " wake" : "");
} else
printf("output");
printf(" state=%d\n", (data >> i) & 1);
}
}
}
static void
hdaa_dump_gpo(struct hdaa_devinfo *devinfo)
{
device_t dev = devinfo->dev;
int i;
uint32_t data;
if (HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap) > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap); i++) {
device_printf(dev, " GPO%d: state=%d", i,
(data >> i) & 1);
}
}
}
static void
hdaa_audio_parse(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
uint32_t res;
int i;
nid_t nid;
nid = devinfo->nid;
res = hda_command(devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_GPIO_COUNT));
devinfo->gpio_cap = res;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"NumGPIO=%d NumGPO=%d "
"NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->gpio_cap));
hdaa_dump_gpi(devinfo);
hdaa_dump_gpio(devinfo);
hdaa_dump_gpo(devinfo);
);
res = hda_command(devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_SUPP_STREAM_FORMATS));
devinfo->supp_stream_formats = res;
res = hda_command(devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_SUPP_PCM_SIZE_RATE));
devinfo->supp_pcm_size_rate = res;
res = hda_command(devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_OUTPUT_AMP_CAP));
devinfo->outamp_cap = res;
res = hda_command(devinfo->dev,
HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_INPUT_AMP_CAP));
devinfo->inamp_cap = res;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
device_printf(devinfo->dev, "Ghost widget! nid=%d!\n", i);
else {
w->devinfo = devinfo;
w->nid = i;
w->enable = 1;
w->selconn = -1;
w->pflags = 0;
w->ossdev = -1;
w->bindas = -1;
w->param.eapdbtl = HDA_INVALID;
hdaa_widget_parse(w);
}
}
}
static void
hdaa_audio_postprocess(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
int i;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
continue;
hdaa_widget_postprocess(w);
}
}
static void
hdaa_audio_ctl_parse(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_ctl *ctls;
struct hdaa_widget *w, *cw;
int i, j, cnt, max, ocap, icap;
int mute, offset, step, size;
/* XXX This is redundant */
max = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->param.outamp_cap != 0)
max++;
if (w->param.inamp_cap != 0) {
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
for (j = 0; j < w->nconns; j++) {
cw = hdaa_widget_get(devinfo,
w->conns[j]);
if (cw == NULL || cw->enable == 0)
continue;
max++;
}
break;
default:
max++;
break;
}
}
}
devinfo->ctlcnt = max;
if (max < 1)
return;
ctls = (struct hdaa_audio_ctl *)malloc(
sizeof(*ctls) * max, M_HDAA, M_ZERO | M_NOWAIT);
if (ctls == NULL) {
/* Blekh! */
device_printf(devinfo->dev, "unable to allocate ctls!\n");
devinfo->ctlcnt = 0;
return;
}
cnt = 0;
for (i = devinfo->startnode; cnt < max && i < devinfo->endnode; i++) {
if (cnt >= max) {
device_printf(devinfo->dev, "%s: Ctl overflow!\n",
__func__);
break;
}
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
ocap = w->param.outamp_cap;
icap = w->param.inamp_cap;
if (ocap != 0) {
mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(ocap);
step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(ocap);
size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(ocap);
offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(ocap);
/*if (offset > step) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"BUGGY outamp: nid=%d "
"[offset=%d > step=%d]\n",
w->nid, offset, step);
);
offset = step;
}*/
ctls[cnt].enable = 1;
ctls[cnt].widget = w;
ctls[cnt].mute = mute;
ctls[cnt].step = step;
ctls[cnt].size = size;
ctls[cnt].offset = offset;
ctls[cnt].left = offset;
ctls[cnt].right = offset;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
w->waspin)
ctls[cnt].ndir = HDAA_CTL_IN;
else
ctls[cnt].ndir = HDAA_CTL_OUT;
ctls[cnt++].dir = HDAA_CTL_OUT;
}
if (icap != 0) {
mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(icap);
step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(icap);
size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(icap);
offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(icap);
/*if (offset > step) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"BUGGY inamp: nid=%d "
"[offset=%d > step=%d]\n",
w->nid, offset, step);
);
offset = step;
}*/
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
for (j = 0; j < w->nconns; j++) {
if (cnt >= max) {
device_printf(devinfo->dev,
"%s: Ctl overflow!\n",
__func__);
break;
}
cw = hdaa_widget_get(devinfo,
w->conns[j]);
if (cw == NULL || cw->enable == 0)
continue;
ctls[cnt].enable = 1;
ctls[cnt].widget = w;
ctls[cnt].childwidget = cw;
ctls[cnt].index = j;
ctls[cnt].mute = mute;
ctls[cnt].step = step;
ctls[cnt].size = size;
ctls[cnt].offset = offset;
ctls[cnt].left = offset;
ctls[cnt].right = offset;
ctls[cnt].ndir = HDAA_CTL_IN;
ctls[cnt++].dir = HDAA_CTL_IN;
}
break;
default:
if (cnt >= max) {
device_printf(devinfo->dev,
"%s: Ctl overflow!\n",
__func__);
break;
}
ctls[cnt].enable = 1;
ctls[cnt].widget = w;
ctls[cnt].mute = mute;
ctls[cnt].step = step;
ctls[cnt].size = size;
ctls[cnt].offset = offset;
ctls[cnt].left = offset;
ctls[cnt].right = offset;
if (w->type ==
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
ctls[cnt].ndir = HDAA_CTL_OUT;
else
ctls[cnt].ndir = HDAA_CTL_IN;
ctls[cnt++].dir = HDAA_CTL_IN;
break;
}
}
}
devinfo->ctl = ctls;
}
static void
hdaa_audio_as_parse(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as;
struct hdaa_widget *w;
int i, j, cnt, max, type, dir, assoc, seq, first, hpredir;
/* Count present associations */
max = 0;
for (j = 1; j < 16; j++) {
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config)
!= j)
continue;
max++;
if (j != 15) /* There could be many 1-pin assocs #15 */
break;
}
}
devinfo->ascnt = max;
if (max < 1)
return;
as = (struct hdaa_audio_as *)malloc(
sizeof(*as) * max, M_HDAA, M_ZERO | M_NOWAIT);
if (as == NULL) {
/* Blekh! */
device_printf(devinfo->dev, "unable to allocate assocs!\n");
devinfo->ascnt = 0;
return;
}
for (i = 0; i < max; i++) {
as[i].hpredir = -1;
as[i].digital = 0;
as[i].num_chans = 1;
as[i].location = -1;
}
/* Scan associations skipping as=0. */
cnt = 0;
for (j = 1; j < 16; j++) {
first = 16;
hpredir = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
assoc = HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config);
seq = HDA_CONFIG_DEFAULTCONF_SEQUENCE(w->wclass.pin.config);
if (assoc != j) {
continue;
}
KASSERT(cnt < max,
("%s: Associations owerflow (%d of %d)",
__func__, cnt, max));
type = w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
/* Get pin direction. */
if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT ||
type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER ||
type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT ||
type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT ||
type == HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT)
dir = HDAA_CTL_OUT;
else
dir = HDAA_CTL_IN;
/* If this is a first pin - create new association. */
if (as[cnt].pincnt == 0) {
as[cnt].enable = 1;
as[cnt].index = j;
as[cnt].dir = dir;
}
if (seq < first)
first = seq;
/* Check association correctness. */
if (as[cnt].pins[seq] != 0) {
device_printf(devinfo->dev, "%s: Duplicate pin %d (%d) "
"in association %d! Disabling association.\n",
__func__, seq, w->nid, j);
as[cnt].enable = 0;
}
if (dir != as[cnt].dir) {
device_printf(devinfo->dev, "%s: Pin %d has wrong "
"direction for association %d! Disabling "
"association.\n",
__func__, w->nid, j);
as[cnt].enable = 0;
}
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
as[cnt].digital |= 0x1;
if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
as[cnt].digital |= 0x2;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap))
as[cnt].digital |= 0x4;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
if (as[cnt].location == -1) {
as[cnt].location =
HDA_CONFIG_DEFAULTCONF_LOCATION(w->wclass.pin.config);
} else if (as[cnt].location !=
HDA_CONFIG_DEFAULTCONF_LOCATION(w->wclass.pin.config)) {
as[cnt].location = -2;
}
/* Headphones with seq=15 may mean redirection. */
if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
seq == 15)
hpredir = 1;
as[cnt].pins[seq] = w->nid;
as[cnt].pincnt++;
/* Association 15 is a multiple unassociated pins. */
if (j == 15)
cnt++;
}
if (j != 15 && as[cnt].pincnt > 0) {
if (hpredir && as[cnt].pincnt > 1)
as[cnt].hpredir = first;
cnt++;
}
}
for (i = 0; i < max; i++) {
if (as[i].dir == HDAA_CTL_IN && (as[i].pincnt == 1 ||
as[i].pins[14] > 0 || as[i].pins[15] > 0))
as[i].mixed = 1;
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"%d associations found:\n", max);
for (i = 0; i < max; i++) {
device_printf(devinfo->dev,
"Association %d (%d) %s%s:\n",
i, as[i].index, (as[i].dir == HDAA_CTL_IN)?"in":"out",
as[i].enable?"":" (disabled)");
for (j = 0; j < 16; j++) {
if (as[i].pins[j] == 0)
continue;
device_printf(devinfo->dev,
" Pin nid=%d seq=%d\n",
as[i].pins[j], j);
}
}
);
devinfo->as = as;
}
/*
* Trace path from DAC to pin.
*/
static nid_t
hdaa_audio_trace_dac(struct hdaa_devinfo *devinfo, int as, int seq, nid_t nid,
int dupseq, int min, int only, int depth)
{
struct hdaa_widget *w;
int i, im = -1;
nid_t m = 0, ret;
if (depth > HDA_PARSE_MAXDEPTH)
return (0);
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return (0);
HDA_BOOTHVERBOSE(
if (!only) {
device_printf(devinfo->dev,
" %*stracing via nid %d\n",
depth + 1, "", w->nid);
}
);
/* Use only unused widgets */
if (w->bindas >= 0 && w->bindas != as) {
HDA_BOOTHVERBOSE(
if (!only) {
device_printf(devinfo->dev,
" %*snid %d busy by association %d\n",
depth + 1, "", w->nid, w->bindas);
}
);
return (0);
}
if (dupseq < 0) {
if (w->bindseqmask != 0) {
HDA_BOOTHVERBOSE(
if (!only) {
device_printf(devinfo->dev,
" %*snid %d busy by seqmask %x\n",
depth + 1, "", w->nid, w->bindseqmask);
}
);
return (0);
}
} else {
/* If this is headphones - allow duplicate first pin. */
if (w->bindseqmask != 0 &&
(w->bindseqmask & (1 << dupseq)) == 0) {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d busy by seqmask %x\n",
depth + 1, "", w->nid, w->bindseqmask);
);
return (0);
}
}
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
/* Do not traverse input. AD1988 has digital monitor
for which we are not ready. */
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
/* If we are tracing HP take only dac of first pin. */
if ((only == 0 || only == w->nid) &&
(w->nid >= min) && (dupseq < 0 || w->nid ==
devinfo->as[as].dacs[0][dupseq]))
m = w->nid;
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
if (depth > 0)
break;
/* Fall */
default:
/* Find reachable DACs with smallest nid respecting constraints. */
for (i = 0; i < w->nconns; i++) {
if (w->connsenable[i] == 0)
continue;
if (w->selconn != -1 && w->selconn != i)
continue;
if ((ret = hdaa_audio_trace_dac(devinfo, as, seq,
w->conns[i], dupseq, min, only, depth + 1)) != 0) {
if (m == 0 || ret < m) {
m = ret;
im = i;
}
if (only || dupseq >= 0)
break;
}
}
if (im >= 0 && only && ((w->nconns > 1 &&
w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR))
w->selconn = im;
break;
}
if (m && only) {
w->bindas = as;
w->bindseqmask |= (1 << seq);
}
HDA_BOOTHVERBOSE(
if (!only) {
device_printf(devinfo->dev,
" %*snid %d returned %d\n",
depth + 1, "", w->nid, m);
}
);
return (m);
}
/*
* Trace path from widget to ADC.
*/
static nid_t
hdaa_audio_trace_adc(struct hdaa_devinfo *devinfo, int as, int seq, nid_t nid,
int mixed, int min, int only, int depth, int *length, int onlylength)
{
struct hdaa_widget *w, *wc;
int i, j, im, lm = HDA_PARSE_MAXDEPTH;
nid_t m = 0, ret;
if (depth > HDA_PARSE_MAXDEPTH)
return (0);
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return (0);
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*stracing via nid %d\n",
depth + 1, "", w->nid);
);
/* Use only unused widgets */
if (w->bindas >= 0 && w->bindas != as) {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d busy by association %d\n",
depth + 1, "", w->nid, w->bindas);
);
return (0);
}
if (!mixed && w->bindseqmask != 0) {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d busy by seqmask %x\n",
depth + 1, "", w->nid, w->bindseqmask);
);
return (0);
}
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
if ((only == 0 || only == w->nid) && (w->nid >= min) &&
(onlylength == 0 || onlylength == depth)) {
m = w->nid;
*length = depth;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
if (depth > 0)
break;
/* Fall */
default:
/* Try to find reachable ADCs with specified nid. */
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
wc = hdaa_widget_get(devinfo, j);
if (wc == NULL || wc->enable == 0)
continue;
im = -1;
for (i = 0; i < wc->nconns; i++) {
if (wc->connsenable[i] == 0)
continue;
if (wc->conns[i] != nid)
continue;
if ((ret = hdaa_audio_trace_adc(devinfo, as, seq,
j, mixed, min, only, depth + 1,
length, onlylength)) != 0) {
if (m == 0 || ret < m ||
(ret == m && *length < lm)) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
m = ret;
im = i;
lm = *length;
} else
*length = lm;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (only)
break;
}
}
if (im >= 0 && only && ((wc->nconns > 1 &&
wc->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR))
wc->selconn = im;
}
break;
}
if (m && only) {
w->bindas = as;
w->bindseqmask |= (1 << seq);
}
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d returned %d\n",
depth + 1, "", w->nid, m);
);
return (m);
}
/*
* Erase trace path of the specified association.
*/
static void
hdaa_audio_undo_trace(struct hdaa_devinfo *devinfo, int as, int seq)
{
struct hdaa_widget *w;
int i;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->bindas == as) {
if (seq >= 0) {
w->bindseqmask &= ~(1 << seq);
if (w->bindseqmask == 0) {
w->bindas = -1;
w->selconn = -1;
}
} else {
w->bindas = -1;
w->bindseqmask = 0;
w->selconn = -1;
}
}
}
}
/*
* Trace association path from DAC to output
*/
static int
hdaa_audio_trace_as_out(struct hdaa_devinfo *devinfo, int as, int seq)
{
struct hdaa_audio_as *ases = devinfo->as;
int i, hpredir;
nid_t min, res;
/* Find next pin */
for (i = seq; i < 16 && ases[as].pins[i] == 0; i++)
;
/* Check if there is no any left. If so - we succeeded. */
if (i == 16)
return (1);
hpredir = (i == 15 && ases[as].fakeredir == 0)?ases[as].hpredir:-1;
min = 0;
do {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Tracing pin %d with min nid %d",
ases[as].pins[i], min);
if (hpredir >= 0)
printf(" and hpredir %d", hpredir);
printf("\n");
);
/* Trace this pin taking min nid into account. */
res = hdaa_audio_trace_dac(devinfo, as, i,
ases[as].pins[i], hpredir, min, 0, 0);
if (res == 0) {
/* If we failed - return to previous and redo it. */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Unable to trace pin %d seq %d with min "
"nid %d",
ases[as].pins[i], i, min);
if (hpredir >= 0)
printf(" and hpredir %d", hpredir);
printf("\n");
);
return (0);
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Pin %d traced to DAC %d",
ases[as].pins[i], res);
if (hpredir >= 0)
printf(" and hpredir %d", hpredir);
if (ases[as].fakeredir)
printf(" with fake redirection");
printf("\n");
);
/* Trace again to mark the path */
hdaa_audio_trace_dac(devinfo, as, i,
ases[as].pins[i], hpredir, min, res, 0);
ases[as].dacs[0][i] = res;
/* We succeeded, so call next. */
if (hdaa_audio_trace_as_out(devinfo, as, i + 1))
return (1);
/* If next failed, we should retry with next min */
hdaa_audio_undo_trace(devinfo, as, i);
ases[as].dacs[0][i] = 0;
min = res + 1;
} while (1);
}
/*
* Check equivalency of two DACs.
*/
static int
hdaa_audio_dacs_equal(struct hdaa_widget *w1, struct hdaa_widget *w2)
{
struct hdaa_devinfo *devinfo = w1->devinfo;
struct hdaa_widget *w3;
int i, j, c1, c2;
if (memcmp(&w1->param, &w2->param, sizeof(w1->param)))
return (0);
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w3 = hdaa_widget_get(devinfo, i);
if (w3 == NULL || w3->enable == 0)
continue;
if (w3->bindas != w1->bindas)
continue;
if (w3->nconns == 0)
continue;
c1 = c2 = -1;
for (j = 0; j < w3->nconns; j++) {
if (w3->connsenable[j] == 0)
continue;
if (w3->conns[j] == w1->nid)
c1 = j;
if (w3->conns[j] == w2->nid)
c2 = j;
}
if (c1 < 0)
continue;
if (c2 < 0)
return (0);
if (w3->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
return (0);
}
return (1);
}
/*
* Check equivalency of two ADCs.
*/
static int
hdaa_audio_adcs_equal(struct hdaa_widget *w1, struct hdaa_widget *w2)
{
struct hdaa_devinfo *devinfo = w1->devinfo;
struct hdaa_widget *w3, *w4;
int i;
if (memcmp(&w1->param, &w2->param, sizeof(w1->param)))
return (0);
if (w1->nconns != 1 || w2->nconns != 1)
return (0);
if (w1->conns[0] == w2->conns[0])
return (1);
w3 = hdaa_widget_get(devinfo, w1->conns[0]);
if (w3 == NULL || w3->enable == 0)
return (0);
w4 = hdaa_widget_get(devinfo, w2->conns[0]);
if (w4 == NULL || w4->enable == 0)
return (0);
if (w3->bindas == w4->bindas && w3->bindseqmask == w4->bindseqmask)
return (1);
if (w4->bindas >= 0)
return (0);
if (w3->type != w4->type)
return (0);
if (memcmp(&w3->param, &w4->param, sizeof(w3->param)))
return (0);
if (w3->nconns != w4->nconns)
return (0);
for (i = 0; i < w3->nconns; i++) {
if (w3->conns[i] != w4->conns[i])
return (0);
}
return (1);
}
/*
* Look for equivalent DAC/ADC to implement second channel.
*/
static void
hdaa_audio_adddac(struct hdaa_devinfo *devinfo, int asid)
{
struct hdaa_audio_as *as = &devinfo->as[asid];
struct hdaa_widget *w1, *w2;
int i, pos;
nid_t nid1, nid2;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Looking for additional %sC "
"for association %d (%d)\n",
(as->dir == HDAA_CTL_OUT) ? "DA" : "AD",
asid, as->index);
);
/* Find the exisitng DAC position and return if found more the one. */
pos = -1;
for (i = 0; i < 16; i++) {
if (as->dacs[0][i] <= 0)
continue;
if (pos >= 0 && as->dacs[0][i] != as->dacs[0][pos])
return;
pos = i;
}
nid1 = as->dacs[0][pos];
w1 = hdaa_widget_get(devinfo, nid1);
w2 = NULL;
for (nid2 = devinfo->startnode; nid2 < devinfo->endnode; nid2++) {
w2 = hdaa_widget_get(devinfo, nid2);
if (w2 == NULL || w2->enable == 0)
continue;
if (w2->bindas >= 0)
continue;
if (w1->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) {
if (w2->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT)
continue;
if (hdaa_audio_dacs_equal(w1, w2))
break;
} else {
if (w2->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
continue;
if (hdaa_audio_adcs_equal(w1, w2))
break;
}
}
if (nid2 >= devinfo->endnode)
return;
w2->bindas = w1->bindas;
w2->bindseqmask = w1->bindseqmask;
if (w1->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" ADC %d considered equal to ADC %d\n", nid2, nid1);
);
w1 = hdaa_widget_get(devinfo, w1->conns[0]);
w2 = hdaa_widget_get(devinfo, w2->conns[0]);
w2->bindas = w1->bindas;
w2->bindseqmask = w1->bindseqmask;
} else {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" DAC %d considered equal to DAC %d\n", nid2, nid1);
);
}
for (i = 0; i < 16; i++) {
if (as->dacs[0][i] <= 0)
continue;
as->dacs[as->num_chans][i] = nid2;
}
as->num_chans++;
}
/*
* Trace association path from input to ADC
*/
static int
hdaa_audio_trace_as_in(struct hdaa_devinfo *devinfo, int as)
{
struct hdaa_audio_as *ases = devinfo->as;
struct hdaa_widget *w;
int i, j, k, length;
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
w = hdaa_widget_get(devinfo, j);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
continue;
if (w->bindas >= 0 && w->bindas != as)
continue;
/* Find next pin */
for (i = 0; i < 16; i++) {
if (ases[as].pins[i] == 0)
continue;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Tracing pin %d to ADC %d\n",
ases[as].pins[i], j);
);
/* Trace this pin taking goal into account. */
if (hdaa_audio_trace_adc(devinfo, as, i,
ases[as].pins[i], 1, 0, j, 0, &length, 0) == 0) {
/* If we failed - return to previous and redo it. */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Unable to trace pin %d to ADC %d, undo traces\n",
ases[as].pins[i], j);
);
hdaa_audio_undo_trace(devinfo, as, -1);
for (k = 0; k < 16; k++)
ases[as].dacs[0][k] = 0;
break;
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Pin %d traced to ADC %d\n",
ases[as].pins[i], j);
);
ases[as].dacs[0][i] = j;
}
if (i == 16)
return (1);
}
return (0);
}
/*
* Trace association path from input to multiple ADCs
*/
static int
hdaa_audio_trace_as_in_mch(struct hdaa_devinfo *devinfo, int as, int seq)
{
struct hdaa_audio_as *ases = devinfo->as;
int i, length;
nid_t min, res;
/* Find next pin */
for (i = seq; i < 16 && ases[as].pins[i] == 0; i++)
;
/* Check if there is no any left. If so - we succeeded. */
if (i == 16)
return (1);
min = 0;
do {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Tracing pin %d with min nid %d",
ases[as].pins[i], min);
printf("\n");
);
/* Trace this pin taking min nid into account. */
res = hdaa_audio_trace_adc(devinfo, as, i,
ases[as].pins[i], 0, min, 0, 0, &length, 0);
if (res == 0) {
/* If we failed - return to previous and redo it. */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Unable to trace pin %d seq %d with min "
"nid %d",
ases[as].pins[i], i, min);
printf("\n");
);
return (0);
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Pin %d traced to ADC %d\n",
ases[as].pins[i], res);
);
/* Trace again to mark the path */
hdaa_audio_trace_adc(devinfo, as, i,
ases[as].pins[i], 0, min, res, 0, &length, length);
ases[as].dacs[0][i] = res;
/* We succeeded, so call next. */
if (hdaa_audio_trace_as_in_mch(devinfo, as, i + 1))
return (1);
/* If next failed, we should retry with next min */
hdaa_audio_undo_trace(devinfo, as, i);
ases[as].dacs[0][i] = 0;
min = res + 1;
} while (1);
}
/*
* Trace input monitor path from mixer to output association.
*/
static int
hdaa_audio_trace_to_out(struct hdaa_devinfo *devinfo, nid_t nid, int depth)
{
struct hdaa_audio_as *ases = devinfo->as;
struct hdaa_widget *w, *wc;
int i, j;
nid_t res = 0;
if (depth > HDA_PARSE_MAXDEPTH)
return (0);
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return (0);
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*stracing via nid %d\n",
depth + 1, "", w->nid);
);
/* Use only unused widgets */
if (depth > 0 && w->bindas != -1) {
if (w->bindas < 0 || ases[w->bindas].dir == HDAA_CTL_OUT) {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d found output association %d\n",
depth + 1, "", w->nid, w->bindas);
);
if (w->bindas >= 0)
w->pflags |= HDAA_ADC_MONITOR;
return (1);
} else {
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d busy by input association %d\n",
depth + 1, "", w->nid, w->bindas);
);
return (0);
}
}
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
/* Do not traverse input. AD1988 has digital monitor
for which we are not ready. */
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
if (depth > 0)
break;
/* Fall */
default:
/* Try to find reachable ADCs with specified nid. */
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
wc = hdaa_widget_get(devinfo, j);
if (wc == NULL || wc->enable == 0)
continue;
for (i = 0; i < wc->nconns; i++) {
if (wc->connsenable[i] == 0)
continue;
if (wc->conns[i] != nid)
continue;
if (hdaa_audio_trace_to_out(devinfo,
j, depth + 1) != 0) {
res = 1;
if (wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
wc->selconn == -1)
wc->selconn = i;
}
}
}
break;
}
if (res && w->bindas == -1)
w->bindas = -2;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" %*snid %d returned %d\n",
depth + 1, "", w->nid, res);
);
return (res);
}
/*
* Trace extra associations (beeper, monitor)
*/
static void
hdaa_audio_trace_as_extra(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w;
int j;
/* Input monitor */
/* Find mixer associated with input, but supplying signal
for output associations. Hope it will be input monitor. */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Tracing input monitor\n");
);
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
w = hdaa_widget_get(devinfo, j);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
continue;
if (w->bindas < 0 || as[w->bindas].dir != HDAA_CTL_IN)
continue;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Tracing nid %d to out\n",
j);
);
if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" nid %d is input monitor\n",
w->nid);
);
w->ossdev = SOUND_MIXER_IMIX;
}
}
/* Other inputs monitor */
/* Find input pins supplying signal for output associations.
Hope it will be input monitoring. */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Tracing other input monitors\n");
);
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
w = hdaa_widget_get(devinfo, j);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (w->bindas < 0 || as[w->bindas].dir != HDAA_CTL_IN)
continue;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" Tracing nid %d to out\n",
j);
);
if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" nid %d is input monitor\n",
w->nid);
);
}
}
/* Beeper */
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Tracing beeper\n");
);
for (j = devinfo->startnode; j < devinfo->endnode; j++) {
w = hdaa_widget_get(devinfo, j);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET)
continue;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Tracing nid %d to out\n",
j);
);
if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
" nid %d traced to out\n",
j);
);
}
w->bindas = -2;
}
}
/*
* Bind assotiations to PCM channels
*/
static void
hdaa_audio_bind_as(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
int i, j, cnt = 0, free;
for (j = 0; j < devinfo->ascnt; j++) {
if (as[j].enable)
cnt += as[j].num_chans;
}
if (devinfo->num_chans == 0) {
devinfo->chans = (struct hdaa_chan *)malloc(
sizeof(struct hdaa_chan) * cnt,
M_HDAA, M_ZERO | M_NOWAIT);
if (devinfo->chans == NULL) {
device_printf(devinfo->dev,
"Channels memory allocation failed!\n");
return;
}
} else {
devinfo->chans = (struct hdaa_chan *)realloc(devinfo->chans,
sizeof(struct hdaa_chan) * (devinfo->num_chans + cnt),
M_HDAA, M_ZERO | M_NOWAIT);
if (devinfo->chans == NULL) {
devinfo->num_chans = 0;
device_printf(devinfo->dev,
"Channels memory allocation failed!\n");
return;
}
/* Fixup relative pointers after realloc */
for (j = 0; j < devinfo->num_chans; j++)
devinfo->chans[j].caps.fmtlist = devinfo->chans[j].fmtlist;
}
free = devinfo->num_chans;
devinfo->num_chans += cnt;
for (j = free; j < free + cnt; j++) {
devinfo->chans[j].devinfo = devinfo;
devinfo->chans[j].as = -1;
}
/* Assign associations in order of their numbers, */
for (j = 0; j < devinfo->ascnt; j++) {
if (as[j].enable == 0)
continue;
for (i = 0; i < as[j].num_chans; i++) {
devinfo->chans[free].as = j;
devinfo->chans[free].asindex = i;
devinfo->chans[free].dir =
(as[j].dir == HDAA_CTL_IN) ? PCMDIR_REC : PCMDIR_PLAY;
hdaa_pcmchannel_setup(&devinfo->chans[free]);
as[j].chans[i] = free;
free++;
}
}
}
static void
hdaa_audio_disable_nonaudio(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
int i;
/* Disable power and volume widgets. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET) {
w->enable = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling nid %d due to it's"
" non-audio type.\n",
w->nid);
);
}
}
}
static void
hdaa_audio_disable_useless(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w, *cw;
struct hdaa_audio_ctl *ctl;
int done, found, i, j, k;
/* Disable useless pins. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
if ((w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) ==
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) {
w->enable = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling pin nid %d due"
" to None connectivity.\n",
w->nid);
);
} else if ((w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK) == 0) {
w->enable = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling unassociated"
" pin nid %d.\n",
w->nid);
);
}
}
}
do {
done = 1;
/* Disable and mute controls for disabled widgets. */
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0)
continue;
if (ctl->widget->enable == 0 ||
(ctl->childwidget != NULL &&
ctl->childwidget->enable == 0)) {
ctl->forcemute = 1;
ctl->muted = HDAA_AMP_MUTE_ALL;
ctl->left = 0;
ctl->right = 0;
ctl->enable = 0;
if (ctl->ndir == HDAA_CTL_IN)
ctl->widget->connsenable[ctl->index] = 0;
done = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling ctl %d nid %d cnid %d due"
" to disabled widget.\n", i,
ctl->widget->nid,
(ctl->childwidget != NULL)?
ctl->childwidget->nid:-1);
);
}
}
/* Disable useless widgets. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
/* Disable inputs with disabled child widgets. */
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j]) {
cw = hdaa_widget_get(devinfo, w->conns[j]);
if (cw == NULL || cw->enable == 0) {
w->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling nid %d connection %d due"
" to disabled child widget.\n",
i, j);
);
}
}
}
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
continue;
/* Disable mixers and selectors without inputs. */
found = 0;
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j]) {
found = 1;
break;
}
}
if (found == 0) {
w->enable = 0;
done = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling nid %d due to all it's"
" inputs disabled.\n", w->nid);
);
}
/* Disable nodes without consumers. */
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
continue;
found = 0;
for (k = devinfo->startnode; k < devinfo->endnode; k++) {
cw = hdaa_widget_get(devinfo, k);
if (cw == NULL || cw->enable == 0)
continue;
for (j = 0; j < cw->nconns; j++) {
if (cw->connsenable[j] && cw->conns[j] == i) {
found = 1;
break;
}
}
}
if (found == 0) {
w->enable = 0;
done = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling nid %d due to all it's"
" consumers disabled.\n", w->nid);
);
}
}
} while (done == 0);
}
static void
hdaa_audio_disable_unas(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w, *cw;
struct hdaa_audio_ctl *ctl;
int i, j, k;
/* Disable unassosiated widgets. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->bindas == -1) {
w->enable = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling unassociated nid %d.\n",
w->nid);
);
}
}
/* Disable input connections on input pin and
* output on output. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (w->bindas < 0)
continue;
if (as[w->bindas].dir == HDAA_CTL_IN) {
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j] == 0)
continue;
w->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling connection to input pin "
"nid %d conn %d.\n",
i, j);
);
}
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_IN, -1, 1);
if (ctl && ctl->enable) {
ctl->forcemute = 1;
ctl->muted = HDAA_AMP_MUTE_ALL;
ctl->left = 0;
ctl->right = 0;
ctl->enable = 0;
}
} else {
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_OUT, -1, 1);
if (ctl && ctl->enable) {
ctl->forcemute = 1;
ctl->muted = HDAA_AMP_MUTE_ALL;
ctl->left = 0;
ctl->right = 0;
ctl->enable = 0;
}
for (k = devinfo->startnode; k < devinfo->endnode; k++) {
cw = hdaa_widget_get(devinfo, k);
if (cw == NULL || cw->enable == 0)
continue;
for (j = 0; j < cw->nconns; j++) {
if (cw->connsenable[j] && cw->conns[j] == i) {
cw->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling connection from output pin "
"nid %d conn %d cnid %d.\n",
k, j, i);
);
if (cw->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
cw->nconns > 1)
continue;
ctl = hdaa_audio_ctl_amp_get(devinfo, k,
HDAA_CTL_IN, j, 1);
if (ctl && ctl->enable) {
ctl->forcemute = 1;
ctl->muted = HDAA_AMP_MUTE_ALL;
ctl->left = 0;
ctl->right = 0;
ctl->enable = 0;
}
}
}
}
}
}
}
static void
hdaa_audio_disable_notselected(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w;
int i, j;
/* On playback path we can safely disable all unseleted inputs. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->nconns <= 1)
continue;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
continue;
if (w->bindas < 0 || as[w->bindas].dir == HDAA_CTL_IN)
continue;
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j] == 0)
continue;
if (w->selconn < 0 || w->selconn == j)
continue;
w->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling unselected connection "
"nid %d conn %d.\n",
i, j);
);
}
}
}
static void
hdaa_audio_disable_crossas(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *ases = devinfo->as;
struct hdaa_widget *w, *cw;
struct hdaa_audio_ctl *ctl;
int i, j;
/* Disable crossassociatement and unwanted crosschannel connections. */
/* ... using selectors */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->nconns <= 1)
continue;
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
continue;
/* Allow any -> mix */
if (w->bindas == -2)
continue;
for (j = 0; j < w->nconns; j++) {
if (w->connsenable[j] == 0)
continue;
cw = hdaa_widget_get(devinfo, w->conns[j]);
if (cw == NULL || w->enable == 0)
continue;
/* Allow mix -> out. */
if (cw->bindas == -2 && w->bindas >= 0 &&
ases[w->bindas].dir == HDAA_CTL_OUT)
continue;
/* Allow mix -> mixed-in. */
if (cw->bindas == -2 && w->bindas >= 0 &&
ases[w->bindas].mixed)
continue;
/* Allow in -> mix. */
if ((w->pflags & HDAA_ADC_MONITOR) &&
cw->bindas >= 0 &&
ases[cw->bindas].dir == HDAA_CTL_IN)
continue;
/* Allow if have common as/seqs. */
if (w->bindas == cw->bindas &&
(w->bindseqmask & cw->bindseqmask) != 0)
continue;
w->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling crossassociatement connection "
"nid %d conn %d cnid %d.\n",
i, j, cw->nid);
);
}
}
/* ... using controls */
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0 || ctl->childwidget == NULL)
continue;
/* Allow any -> mix */
if (ctl->widget->bindas == -2)
continue;
/* Allow mix -> out. */
if (ctl->childwidget->bindas == -2 &&
ctl->widget->bindas >= 0 &&
ases[ctl->widget->bindas].dir == HDAA_CTL_OUT)
continue;
/* Allow mix -> mixed-in. */
if (ctl->childwidget->bindas == -2 &&
ctl->widget->bindas >= 0 &&
ases[ctl->widget->bindas].mixed)
continue;
/* Allow in -> mix. */
if ((ctl->widget->pflags & HDAA_ADC_MONITOR) &&
ctl->childwidget->bindas >= 0 &&
ases[ctl->childwidget->bindas].dir == HDAA_CTL_IN)
continue;
/* Allow if have common as/seqs. */
if (ctl->widget->bindas == ctl->childwidget->bindas &&
(ctl->widget->bindseqmask & ctl->childwidget->bindseqmask) != 0)
continue;
ctl->forcemute = 1;
ctl->muted = HDAA_AMP_MUTE_ALL;
ctl->left = 0;
ctl->right = 0;
ctl->enable = 0;
if (ctl->ndir == HDAA_CTL_IN)
ctl->widget->connsenable[ctl->index] = 0;
HDA_BOOTHVERBOSE(
device_printf(devinfo->dev,
" Disabling crossassociatement connection "
"ctl %d nid %d cnid %d.\n", i,
ctl->widget->nid,
ctl->childwidget->nid);
);
}
}
/*
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
* Find controls to control amplification for source and calculate possible
* amplification range.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
static int
hdaa_audio_ctl_source_amp(struct hdaa_devinfo *devinfo, nid_t nid, int index,
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int ossdev, int ctlable, int depth, int *minamp, int *maxamp)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_widget *w, *wc;
struct hdaa_audio_ctl *ctl;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int i, j, conns = 0, tminamp, tmaxamp, cminamp, cmaxamp, found = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (depth > HDA_PARSE_MAXDEPTH)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Count number of active inputs. */
if (depth > 0) {
for (j = 0; j < w->nconns; j++) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (!w->connsenable[j])
continue;
conns++;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/* If this is not a first step - use input mixer.
Pins have common input ctl so care must be taken. */
if (depth > 0 && ctlable && (conns == 1 ||
w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)) {
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_IN,
index, 1);
if (ctl) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
ctl->ossmask |= (1 << ossdev);
found++;
if (*minamp == *maxamp) {
*minamp += MINQDB(ctl);
*maxamp += MAXQDB(ctl);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/* If widget has own ossdev - not traverse it.
It will be traversed on it's own. */
if (w->ossdev >= 0 && depth > 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* We must not traverse pin */
if ((w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) &&
depth > 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* record that this widget exports such signal, */
w->ossmask |= (1 << ossdev);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* If signals mixed, we can't assign controls farther.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
* Ignore this on depth zero. Caller must knows why.
*/
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (conns > 1 &&
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ctlable = 0;
if (ctlable) {
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_OUT, -1, 1);
if (ctl) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
ctl->ossmask |= (1 << ossdev);
found++;
if (*minamp == *maxamp) {
*minamp += MINQDB(ctl);
*maxamp += MAXQDB(ctl);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
cminamp = cmaxamp = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
wc = hdaa_widget_get(devinfo, i);
if (wc == NULL || wc->enable == 0)
continue;
for (j = 0; j < wc->nconns; j++) {
if (wc->connsenable[j] && wc->conns[j] == nid) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
tminamp = tmaxamp = 0;
found += hdaa_audio_ctl_source_amp(devinfo,
wc->nid, j, ossdev, ctlable, depth + 1,
&tminamp, &tmaxamp);
if (cminamp == 0 && cmaxamp == 0) {
cminamp = tminamp;
cmaxamp = tmaxamp;
} else if (tminamp != tmaxamp) {
cminamp = imax(cminamp, tminamp);
cmaxamp = imin(cmaxamp, tmaxamp);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (*minamp == *maxamp && cminamp < cmaxamp) {
*minamp += cminamp;
*maxamp += cmaxamp;
}
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
/*
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
* Find controls to control amplification for destination and calculate
* possible amplification range.
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
*/
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
static int
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_audio_ctl_dest_amp(struct hdaa_devinfo *devinfo, nid_t nid, int index,
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int ossdev, int depth, int *minamp, int *maxamp)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w, *wc;
struct hdaa_audio_ctl *ctl;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int i, j, consumers, tminamp, tmaxamp, cminamp, cmaxamp, found = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (depth > HDA_PARSE_MAXDEPTH)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (depth > 0) {
/* If this node produce output for several consumers,
we can't touch it. */
consumers = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
wc = hdaa_widget_get(devinfo, i);
if (wc == NULL || wc->enable == 0)
continue;
for (j = 0; j < wc->nconns; j++) {
if (wc->connsenable[j] && wc->conns[j] == nid)
consumers++;
}
}
/* The only exception is if real HP redirection is configured
and this is a duplication point.
XXX: Actually exception is not completely correct.
XXX: Duplication point check is not perfect. */
if ((consumers == 2 && (w->bindas < 0 ||
as[w->bindas].hpredir < 0 || as[w->bindas].fakeredir ||
(w->bindseqmask & (1 << 15)) == 0)) ||
consumers > 2)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Else use it's output mixer. */
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_OUT, -1, 1);
if (ctl) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
ctl->ossmask |= (1 << ossdev);
found++;
if (*minamp == *maxamp) {
*minamp += MINQDB(ctl);
*maxamp += MAXQDB(ctl);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
/* We must not traverse pin */
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
depth > 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
cminamp = cmaxamp = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (i = 0; i < w->nconns; i++) {
if (w->connsenable[i] == 0)
continue;
if (index >= 0 && i != index)
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
tminamp = tmaxamp = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
HDAA_CTL_IN, i, 1);
if (ctl) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
ctl->ossmask |= (1 << ossdev);
found++;
if (*minamp == *maxamp) {
tminamp += MINQDB(ctl);
tmaxamp += MAXQDB(ctl);
}
}
found += hdaa_audio_ctl_dest_amp(devinfo, w->conns[i], -1, ossdev,
depth + 1, &tminamp, &tmaxamp);
if (cminamp == 0 && cmaxamp == 0) {
cminamp = tminamp;
cmaxamp = tmaxamp;
} else if (tminamp != tmaxamp) {
cminamp = imax(cminamp, tminamp);
cmaxamp = imin(cmaxamp, tmaxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (*minamp == *maxamp && cminamp < cmaxamp) {
*minamp += cminamp;
*maxamp += cmaxamp;
}
return (found);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
/*
* Assign OSS names to sound sources
*/
static void
hdaa_audio_assign_names(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w;
int i, j;
int type = -1, use, used = 0;
static const int types[7][13] = {
{ SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2,
SOUND_MIXER_LINE3, -1 }, /* line */
{ SOUND_MIXER_MONITOR, SOUND_MIXER_MIC, -1 }, /* int mic */
{ SOUND_MIXER_MIC, SOUND_MIXER_MONITOR, -1 }, /* ext mic */
{ SOUND_MIXER_CD, -1 }, /* cd */
{ SOUND_MIXER_SPEAKER, -1 }, /* speaker */
{ SOUND_MIXER_DIGITAL1, SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3,
-1 }, /* digital */
{ SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2,
SOUND_MIXER_LINE3, SOUND_MIXER_PHONEIN, SOUND_MIXER_PHONEOUT,
SOUND_MIXER_VIDEO, SOUND_MIXER_RADIO, SOUND_MIXER_DIGITAL1,
SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3, SOUND_MIXER_MONITOR,
-1 } /* others */
};
/* Surely known names */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->bindas == -1)
continue;
use = -1;
switch (w->type) {
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
if (as[w->bindas].dir == HDAA_CTL_OUT)
break;
type = -1;
switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN:
type = 0;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
if ((w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK)
== HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK)
break;
type = 1;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_CD:
type = 3;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
type = 4;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN:
case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN:
type = 5;
break;
}
if (type == -1)
break;
j = 0;
while (types[type][j] >= 0 &&
(used & (1 << types[type][j])) != 0) {
j++;
}
if (types[type][j] >= 0)
use = types[type][j];
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
use = SOUND_MIXER_PCM;
break;
case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
use = SOUND_MIXER_SPEAKER;
break;
default:
break;
}
if (use >= 0) {
w->ossdev = use;
used |= (1 << use);
}
}
/* Semi-known names */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->ossdev >= 0)
continue;
if (w->bindas == -1)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (as[w->bindas].dir == HDAA_CTL_OUT)
continue;
type = -1;
switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT:
case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
case HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT:
case HDA_CONFIG_DEFAULTCONF_DEVICE_AUX:
type = 0;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
type = 2;
break;
case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT:
case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT:
type = 5;
break;
}
if (type == -1)
break;
j = 0;
while (types[type][j] >= 0 &&
(used & (1 << types[type][j])) != 0) {
j++;
}
if (types[type][j] >= 0) {
w->ossdev = types[type][j];
used |= (1 << types[type][j]);
}
}
/* Others */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->ossdev >= 0)
continue;
if (w->bindas == -1)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (as[w->bindas].dir == HDAA_CTL_OUT)
continue;
j = 0;
while (types[6][j] >= 0 &&
(used & (1 << types[6][j])) != 0) {
j++;
}
if (types[6][j] >= 0) {
w->ossdev = types[6][j];
used |= (1 << types[6][j]);
}
}
}
static void
hdaa_audio_build_tree(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
int j, res;
/* Trace all associations in order of their numbers. */
for (j = 0; j < devinfo->ascnt; j++) {
if (as[j].enable == 0)
continue;
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Tracing association %d (%d)\n", j, as[j].index);
);
if (as[j].dir == HDAA_CTL_OUT) {
retry:
res = hdaa_audio_trace_as_out(devinfo, j, 0);
if (res == 0 && as[j].hpredir >= 0 &&
as[j].fakeredir == 0) {
/* If CODEC can't do analog HP redirection
try to make it using one more DAC. */
as[j].fakeredir = 1;
goto retry;
}
} else if (as[j].mixed)
res = hdaa_audio_trace_as_in(devinfo, j);
else
res = hdaa_audio_trace_as_in_mch(devinfo, j, 0);
if (res) {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Association %d (%d) trace succeeded\n",
j, as[j].index);
);
} else {
HDA_BOOTVERBOSE(
device_printf(devinfo->dev,
"Association %d (%d) trace failed\n",
j, as[j].index);
);
as[j].enable = 0;
}
}
/* Look for additional DACs/ADCs. */
for (j = 0; j < devinfo->ascnt; j++) {
if (as[j].enable == 0)
continue;
hdaa_audio_adddac(devinfo, j);
}
/* Trace mixer and beeper pseudo associations. */
hdaa_audio_trace_as_extra(devinfo);
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
/*
* Store in pdevinfo new data about whether and how we can control signal
* for OSS device to/from specified widget.
*/
static void
hdaa_adjust_amp(struct hdaa_widget *w, int ossdev,
int found, int minamp, int maxamp)
{
struct hdaa_devinfo *devinfo = w->devinfo;
struct hdaa_pcm_devinfo *pdevinfo;
if (w->bindas >= 0)
pdevinfo = devinfo->as[w->bindas].pdevinfo;
else
pdevinfo = &devinfo->devs[0];
if (found)
pdevinfo->ossmask |= (1 << ossdev);
if (minamp == 0 && maxamp == 0)
return;
if (pdevinfo->minamp[ossdev] == 0 && pdevinfo->maxamp[ossdev] == 0) {
pdevinfo->minamp[ossdev] = minamp;
pdevinfo->maxamp[ossdev] = maxamp;
} else {
pdevinfo->minamp[ossdev] = imax(pdevinfo->minamp[ossdev], minamp);
pdevinfo->maxamp[ossdev] = imin(pdevinfo->maxamp[ossdev], maxamp);
}
}
/*
* Trace signals from/to all possible sources/destionstions to find possible
* recording sources, OSS device control ranges and to assign controls.
*/
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
static void
hdaa_audio_assign_mixers(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w, *cw;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
int i, j, minamp, maxamp, found;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Assign mixers to the tree. */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
minamp = maxamp = 0;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET ||
(w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
as[w->bindas].dir == HDAA_CTL_IN)) {
if (w->ossdev < 0)
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
found = hdaa_audio_ctl_source_amp(devinfo, w->nid, -1,
w->ossdev, 1, 0, &minamp, &maxamp);
hdaa_adjust_amp(w, w->ossdev, found, minamp, maxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
found = hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
SOUND_MIXER_RECLEV, 0, &minamp, &maxamp);
hdaa_adjust_amp(w, SOUND_MIXER_RECLEV, found, minamp, maxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
as[w->bindas].dir == HDAA_CTL_OUT) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
found = hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
SOUND_MIXER_VOLUME, 0, &minamp, &maxamp);
hdaa_adjust_amp(w, SOUND_MIXER_VOLUME, found, minamp, maxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
if (w->ossdev == SOUND_MIXER_IMIX) {
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
minamp = maxamp = 0;
found = hdaa_audio_ctl_source_amp(devinfo, w->nid, -1,
w->ossdev, 1, 0, &minamp, &maxamp);
if (minamp == maxamp) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* If we are unable to control input monitor
as source - try to control it as destination. */
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
found += hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
w->ossdev, 0, &minamp, &maxamp);
w->pflags |= HDAA_IMIX_AS_DST;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
hdaa_adjust_amp(w, w->ossdev, found, minamp, maxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
if (w->pflags & HDAA_ADC_MONITOR) {
for (j = 0; j < w->nconns; j++) {
if (!w->connsenable[j])
continue;
cw = hdaa_widget_get(devinfo, w->conns[j]);
if (cw == NULL || cw->enable == 0)
continue;
if (cw->bindas == -1)
continue;
if (cw->bindas >= 0 &&
as[cw->bindas].dir != HDAA_CTL_IN)
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
minamp = maxamp = 0;
found = hdaa_audio_ctl_dest_amp(devinfo,
w->nid, j, SOUND_MIXER_IGAIN, 0,
&minamp, &maxamp);
hdaa_adjust_amp(w, SOUND_MIXER_IGAIN,
found, minamp, maxamp);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
}
}
static void
hdaa_audio_prepare_pin_ctrl(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w;
uint32_t pincap;
int i;
for (i = 0; i < devinfo->nodecnt; i++) {
w = &devinfo->widget[i];
if (w == NULL)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
w->waspin == 0)
continue;
pincap = w->wclass.pin.cap;
/* Disable everything. */
w->wclass.pin.ctrl &= ~(
HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE |
HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE |
HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE |
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK);
if (w->enable == 0) {
/* Pin is unused so left it disabled. */
continue;
} else if (w->waspin) {
/* Enable input for beeper input. */
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE;
} else if (w->bindas < 0 || as[w->bindas].enable == 0) {
/* Pin is unused so left it disabled. */
continue;
} else if (as[w->bindas].dir == HDAA_CTL_IN) {
/* Input pin, configure for input. */
if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE;
if ((devinfo->quirks & HDAA_QUIRK_IVREF100) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
else if ((devinfo->quirks & HDAA_QUIRK_IVREF80) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
else if ((devinfo->quirks & HDAA_QUIRK_IVREF50) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
} else {
/* Output pin, configure for output. */
if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap) &&
(w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT)
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE;
if ((devinfo->quirks & HDAA_QUIRK_OVREF100) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
else if ((devinfo->quirks & HDAA_QUIRK_OVREF80) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
else if ((devinfo->quirks & HDAA_QUIRK_OVREF50) &&
HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
w->wclass.pin.ctrl |=
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
}
}
}
static void
hdaa_audio_ctl_commit(struct hdaa_devinfo *devinfo)
{
struct hdaa_audio_ctl *ctl;
int i, z;
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0 || ctl->ossmask != 0) {
/* Mute disabled and mixer controllable controls.
* Last will be initialized by mixer_init().
* This expected to reduce click on startup. */
hdaa_audio_ctl_amp_set(ctl, HDAA_AMP_MUTE_ALL, 0, 0);
continue;
}
/* Init fixed controls to 0dB amplification. */
z = ctl->offset;
if (z > ctl->step)
z = ctl->step;
hdaa_audio_ctl_amp_set(ctl, HDAA_AMP_MUTE_NONE, z, z);
}
}
static void
hdaa_gpio_commit(struct hdaa_devinfo *devinfo)
{
uint32_t gdata, gmask, gdir;
int i, numgpio;
numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
if (devinfo->gpio != 0 && numgpio != 0) {
gdata = hda_command(devinfo->dev,
HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
gmask = hda_command(devinfo->dev,
HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
gdir = hda_command(devinfo->dev,
HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
for (i = 0; i < numgpio; i++) {
if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_SET(i)) {
gdata |= (1 << i);
gmask |= (1 << i);
gdir |= (1 << i);
} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_CLEAR(i)) {
gdata &= ~(1 << i);
gmask |= (1 << i);
gdir |= (1 << i);
} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_DISABLE(i)) {
gmask &= ~(1 << i);
} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_INPUT(i)) {
gmask |= (1 << i);
gdir &= ~(1 << i);
}
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev, "GPIO commit\n");
);
hda_command(devinfo->dev,
HDA_CMD_SET_GPIO_ENABLE_MASK(0, devinfo->nid, gmask));
hda_command(devinfo->dev,
HDA_CMD_SET_GPIO_DIRECTION(0, devinfo->nid, gdir));
hda_command(devinfo->dev,
HDA_CMD_SET_GPIO_DATA(0, devinfo->nid, gdata));
HDA_BOOTVERBOSE(
hdaa_dump_gpio(devinfo);
);
}
}
static void
hdaa_gpo_commit(struct hdaa_devinfo *devinfo)
{
uint32_t gdata;
int i, numgpo;
numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
if (devinfo->gpo != 0 && numgpo != 0) {
gdata = hda_command(devinfo->dev,
HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
for (i = 0; i < numgpo; i++) {
if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_SET(i)) {
gdata |= (1 << i);
} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
HDAA_GPIO_CLEAR(i)) {
gdata &= ~(1 << i);
}
}
HDA_BOOTVERBOSE(
device_printf(devinfo->dev, "GPO commit\n");
);
hda_command(devinfo->dev,
HDA_CMD_SET_GPO_DATA(0, devinfo->nid, gdata));
HDA_BOOTVERBOSE(
hdaa_dump_gpo(devinfo);
);
}
}
static void
hdaa_audio_commit(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
int i;
/* Commit controls. */
hdaa_audio_ctl_commit(devinfo);
/* Commit selectors, pins and EAPD. */
for (i = 0; i < devinfo->nodecnt; i++) {
w = &devinfo->widget[i];
if (w == NULL)
continue;
if (w->selconn == -1)
w->selconn = 0;
if (w->nconns > 0)
hdaa_widget_connection_select(w, w->selconn);
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
w->waspin) {
hda_command(devinfo->dev,
HDA_CMD_SET_PIN_WIDGET_CTRL(0, w->nid,
w->wclass.pin.ctrl));
}
if (w->param.eapdbtl != HDA_INVALID) {
uint32_t val;
val = w->param.eapdbtl;
if (devinfo->quirks &
HDAA_QUIRK_EAPDINV)
val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
hda_command(devinfo->dev,
HDA_CMD_SET_EAPD_BTL_ENABLE(0, w->nid,
val));
}
}
hdaa_gpio_commit(devinfo);
hdaa_gpo_commit(devinfo);
}
static void
hdaa_powerup(struct hdaa_devinfo *devinfo)
{
int i;
hda_command(devinfo->dev,
HDA_CMD_SET_POWER_STATE(0,
devinfo->nid, HDA_CMD_POWER_STATE_D0));
DELAY(100);
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
hda_command(devinfo->dev,
HDA_CMD_SET_POWER_STATE(0,
i, HDA_CMD_POWER_STATE_D0));
}
DELAY(1000);
}
static int
hdaa_pcmchannel_setup(struct hdaa_chan *ch)
{
struct hdaa_devinfo *devinfo = ch->devinfo;
struct hdaa_audio_as *as = devinfo->as;
struct hdaa_widget *w;
uint32_t cap, fmtcap, pcmcap;
int i, j, ret, channels, onlystereo;
uint16_t pinset;
ch->caps = hdaa_caps;
ch->caps.fmtlist = ch->fmtlist;
ch->bit16 = 1;
ch->bit32 = 0;
ch->pcmrates[0] = 48000;
ch->pcmrates[1] = 0;
ch->stripecap = 0xff;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ret = 0;
channels = 0;
onlystereo = 1;
pinset = 0;
fmtcap = devinfo->supp_stream_formats;
pcmcap = devinfo->supp_pcm_size_rate;
for (i = 0; i < 16; i++) {
/* Check as is correct */
if (ch->as < 0)
break;
/* Cound only present DACs */
if (as[ch->as].dacs[ch->asindex][i] <= 0)
continue;
/* Ignore duplicates */
for (j = 0; j < ret; j++) {
if (ch->io[j] == as[ch->as].dacs[ch->asindex][i])
break;
}
if (j < ret)
continue;
w = hdaa_widget_get(devinfo, as[ch->as].dacs[ch->asindex][i]);
if (w == NULL || w->enable == 0)
continue;
cap = w->param.supp_stream_formats;
if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap) &&
!HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
continue;
/* Many CODECs does not declare AC3 support on SPDIF.
I don't beleave that they doesn't support it! */
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
cap |= HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK;
if (ret == 0) {
fmtcap = cap;
pcmcap = w->param.supp_pcm_size_rate;
} else {
fmtcap &= cap;
pcmcap &= w->param.supp_pcm_size_rate;
}
ch->io[ret++] = as[ch->as].dacs[ch->asindex][i];
ch->stripecap &= w->wclass.conv.stripecap;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
/* Do not count redirection pin/dac channels. */
if (i == 15 && as[ch->as].hpredir >= 0)
continue;
channels += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
if (HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) != 1)
onlystereo = 0;
pinset |= (1 << i);
}
ch->io[ret] = -1;
ch->channels = channels;
if (as[ch->as].fakeredir)
ret--;
/* Standard speaks only about stereo pins and playback, ... */
if ((!onlystereo) || as[ch->as].mixed)
pinset = 0;
/* ..., but there it gives us info about speakers layout. */
as[ch->as].pinset = pinset;
ch->supp_stream_formats = fmtcap;
ch->supp_pcm_size_rate = pcmcap;
/*
* 8bit = 0
* 16bit = 1
* 20bit = 2
* 24bit = 3
* 32bit = 4
*/
if (ret > 0) {
i = 0;
if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(fmtcap)) {
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(pcmcap))
ch->bit16 = 1;
else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(pcmcap))
ch->bit16 = 0;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(pcmcap))
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->bit32 = 3;
else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap))
ch->bit32 = 2;
else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(pcmcap))
ch->bit32 = 4;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (!(devinfo->quirks & HDAA_QUIRK_FORCESTEREO)) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 1, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 1, 0);
}
if (channels >= 2) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 2, 0);
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (channels >= 3 && !onlystereo) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 3, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 3, 0);
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 3, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 3, 1);
}
if (channels >= 4) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 0);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (!onlystereo) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 1);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (channels >= 5 && !onlystereo) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 5, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 5, 0);
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 5, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 5, 1);
}
if (channels >= 6) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 1);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (!onlystereo) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 0);
}
}
if (channels >= 7 && !onlystereo) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 7, 0);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 7, 0);
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 7, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 7, 1);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (channels >= 8) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 8, 1);
if (ch->bit32)
ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 8, 1);
}
}
if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(fmtcap)) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_AC3, 2, 0);
if (channels >= 8) {
ch->fmtlist[i++] = SND_FORMAT(AFMT_AC3, 8, 0);
ch->fmtlist[i++] = SND_FORMAT(AFMT_AC3, 8, 1);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
ch->fmtlist[i] = 0;
i = 0;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(pcmcap))
ch->pcmrates[i++] = 8000;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(pcmcap))
ch->pcmrates[i++] = 11025;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(pcmcap))
ch->pcmrates[i++] = 16000;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(pcmcap))
ch->pcmrates[i++] = 22050;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(pcmcap))
ch->pcmrates[i++] = 32000;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(pcmcap))
ch->pcmrates[i++] = 44100;
/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(pcmcap)) */
ch->pcmrates[i++] = 48000;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(pcmcap))
ch->pcmrates[i++] = 88200;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(pcmcap))
ch->pcmrates[i++] = 96000;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(pcmcap))
ch->pcmrates[i++] = 176400;
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(pcmcap))
ch->pcmrates[i++] = 192000;
/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(pcmcap)) */
ch->pcmrates[i] = 0;
if (i > 0) {
ch->caps.minspeed = ch->pcmrates[0];
ch->caps.maxspeed = ch->pcmrates[i - 1];
}
}
return (ret);
}
static void
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
hdaa_prepare_pcms(struct hdaa_devinfo *devinfo)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
{
struct hdaa_audio_as *as = devinfo->as;
int i, j, k, apdev = 0, ardev = 0, dpdev = 0, drdev = 0;
for (i = 0; i < devinfo->ascnt; i++) {
if (as[i].enable == 0)
continue;
if (as[i].dir == HDAA_CTL_IN) {
if (as[i].digital)
drdev++;
else
ardev++;
} else {
if (as[i].digital)
dpdev++;
else
apdev++;
}
}
devinfo->num_devs =
max(ardev, apdev) + max(drdev, dpdev);
devinfo->devs =
(struct hdaa_pcm_devinfo *)malloc(
devinfo->num_devs * sizeof(struct hdaa_pcm_devinfo),
M_HDAA, M_ZERO | M_NOWAIT);
if (devinfo->devs == NULL) {
device_printf(devinfo->dev,
"Unable to allocate memory for devices\n");
return;
}
for (i = 0; i < devinfo->num_devs; i++) {
devinfo->devs[i].index = i;
devinfo->devs[i].devinfo = devinfo;
devinfo->devs[i].playas = -1;
devinfo->devs[i].recas = -1;
devinfo->devs[i].digital = 255;
}
for (i = 0; i < devinfo->ascnt; i++) {
if (as[i].enable == 0)
continue;
for (j = 0; j < devinfo->num_devs; j++) {
if (devinfo->devs[j].digital != 255 &&
(!devinfo->devs[j].digital) !=
(!as[i].digital))
continue;
if (as[i].dir == HDAA_CTL_IN) {
if (devinfo->devs[j].recas >= 0)
continue;
devinfo->devs[j].recas = i;
} else {
if (devinfo->devs[j].playas >= 0)
continue;
devinfo->devs[j].playas = i;
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
as[i].pdevinfo = &devinfo->devs[j];
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (k = 0; k < as[i].num_chans; k++) {
devinfo->chans[as[i].chans[k]].pdevinfo =
&devinfo->devs[j];
}
devinfo->devs[j].digital = as[i].digital;
break;
}
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
}
static void
hdaa_create_pcms(struct hdaa_devinfo *devinfo)
{
int i;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
for (i = 0; i < devinfo->num_devs; i++) {
struct hdaa_pcm_devinfo *pdevinfo = &devinfo->devs[i];
pdevinfo->dev = device_add_child(devinfo->dev, "pcm", -1);
device_set_ivars(pdevinfo->dev, (void *)pdevinfo);
}
}
static void
hdaa_dump_ctls(struct hdaa_pcm_devinfo *pdevinfo, const char *banner, uint32_t flag)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_audio_ctl *ctl;
char buf[64];
int i, j, printed;
if (flag == 0) {
flag = ~(SOUND_MASK_VOLUME | SOUND_MASK_PCM |
SOUND_MASK_CD | SOUND_MASK_LINE | SOUND_MASK_RECLEV |
SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IGAIN |
SOUND_MASK_OGAIN | SOUND_MASK_IMIX | SOUND_MASK_MONITOR);
}
for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
if ((flag & (1 << j)) == 0)
continue;
i = 0;
printed = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
if (ctl->enable == 0 ||
ctl->widget->enable == 0)
continue;
if (!((pdevinfo->playas >= 0 &&
ctl->widget->bindas == pdevinfo->playas) ||
(pdevinfo->recas >= 0 &&
ctl->widget->bindas == pdevinfo->recas) ||
(ctl->widget->bindas == -2 && pdevinfo->index == 0)))
continue;
if ((ctl->ossmask & (1 << j)) == 0)
continue;
if (printed == 0) {
device_printf(pdevinfo->dev, "\n");
if (banner != NULL) {
device_printf(pdevinfo->dev, "%s", banner);
} else {
device_printf(pdevinfo->dev, "Unknown Ctl");
}
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
printf(" (OSS: %s)",
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_audio_ctl_ossmixer_mask2allname(1 << j,
buf, sizeof(buf)));
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (pdevinfo->ossmask & (1 << j)) {
printf(": %+d/%+ddB\n",
pdevinfo->minamp[j] / 4,
pdevinfo->maxamp[j] / 4);
} else
printf("\n");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
device_printf(pdevinfo->dev, " |\n");
printed = 1;
}
device_printf(pdevinfo->dev, " +- ctl %2d (nid %3d %s", i,
ctl->widget->nid,
(ctl->ndir == HDAA_CTL_IN)?"in ":"out");
if (ctl->ndir == HDAA_CTL_IN && ctl->ndir == ctl->dir)
printf(" %2d): ", ctl->index);
else
printf("): ");
if (ctl->step > 0) {
printf("%+d/%+ddB (%d steps)%s\n",
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
MINQDB(ctl) / 4,
MAXQDB(ctl) / 4,
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
ctl->step + 1,
ctl->mute?" + mute":"");
} else
printf("%s\n", ctl->mute?"mute":"");
}
}
}
static void
hdaa_dump_audio_formats(device_t dev, uint32_t fcap, uint32_t pcmcap)
{
uint32_t cap;
cap = fcap;
if (cap != 0) {
device_printf(dev, " Stream cap: 0x%08x\n", cap);
device_printf(dev, " ");
if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
printf(" AC3");
if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap))
printf(" FLOAT32");
if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap))
printf(" PCM");
printf("\n");
}
cap = pcmcap;
if (cap != 0) {
device_printf(dev, " PCM cap: 0x%08x\n", cap);
device_printf(dev, " ");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(cap))
printf(" 8");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(cap))
printf(" 16");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(cap))
printf(" 20");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(cap))
printf(" 24");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(cap))
printf(" 32");
printf(" bits,");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(cap))
printf(" 8");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(cap))
printf(" 11");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(cap))
printf(" 16");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(cap))
printf(" 22");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(cap))
printf(" 32");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(cap))
printf(" 44");
printf(" 48");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(cap))
printf(" 88");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(cap))
printf(" 96");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(cap))
printf(" 176");
if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(cap))
printf(" 192");
printf(" KHz\n");
}
}
static void
hdaa_dump_pin(struct hdaa_widget *w)
{
uint32_t pincap;
pincap = w->wclass.pin.cap;
device_printf(w->devinfo->dev, " Pin cap: 0x%08x\n", pincap);
device_printf(w->devinfo->dev, " ");
if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap))
printf(" ISC");
if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap))
printf(" TRQD");
if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap))
printf(" PDC");
if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap))
printf(" HP");
if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
printf(" OUT");
if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
printf(" IN");
if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap))
printf(" BAL");
if (HDA_PARAM_PIN_CAP_HDMI(pincap))
printf(" HDMI");
if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) {
printf(" VREF[");
if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
printf(" 50");
if (HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
printf(" 80");
if (HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
printf(" 100");
if (HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(pincap))
printf(" GROUND");
if (HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(pincap))
printf(" HIZ");
printf(" ]");
}
if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap))
printf(" EAPD");
if (HDA_PARAM_PIN_CAP_DP(pincap))
printf(" DP");
if (HDA_PARAM_PIN_CAP_HBR(pincap))
printf(" HBR");
printf("\n");
device_printf(w->devinfo->dev, " Pin config: 0x%08x\n",
w->wclass.pin.config);
device_printf(w->devinfo->dev, " Pin control: 0x%08x", w->wclass.pin.ctrl);
if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE)
printf(" HP");
if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE)
printf(" IN");
if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE)
printf(" OUT");
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
if ((w->wclass.pin.ctrl &
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) == 0x03)
printf(" HBR");
else if ((w->wclass.pin.ctrl &
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) != 0)
printf(" EPTs");
} else {
if ((w->wclass.pin.ctrl &
HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) != 0)
printf(" VREFs");
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
printf("\n");
}
static void
hdaa_dump_pin_config(struct hdaa_widget *w, uint32_t conf)
{
device_printf(w->devinfo->dev, "%2d %08x %-2d %-2d "
"%-13s %-5s %-7s %-10s %-7s %d%s\n",
w->nid, conf,
HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf),
HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf),
HDA_DEVS[HDA_CONFIG_DEFAULTCONF_DEVICE(conf)],
HDA_CONNS[HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf)],
HDA_CONNECTORS[HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf)],
HDA_LOCS[HDA_CONFIG_DEFAULTCONF_LOCATION(conf)],
HDA_COLORS[HDA_CONFIG_DEFAULTCONF_COLOR(conf)],
HDA_CONFIG_DEFAULTCONF_MISC(conf),
(w->enable == 0)?" DISA":"");
}
static void
hdaa_dump_pin_configs(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
int i;
device_printf(devinfo->dev, "nid 0x as seq "
"device conn jack loc color misc\n");
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
hdaa_dump_pin_config(w, w->wclass.pin.config);
}
}
static void
hdaa_dump_amp(device_t dev, uint32_t cap, char *banner)
{
device_printf(dev, " %s amp: 0x%08x\n", banner, cap);
device_printf(dev, " "
"mute=%d step=%d size=%d offset=%d\n",
HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(cap),
HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(cap),
HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(cap),
HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(cap));
}
static void
hdaa_dump_nodes(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w, *cw;
char buf[64];
int i, j;
device_printf(devinfo->dev, "\n");
device_printf(devinfo->dev, "Default Parameter\n");
device_printf(devinfo->dev, "-----------------\n");
hdaa_dump_audio_formats(devinfo->dev,
devinfo->supp_stream_formats,
devinfo->supp_pcm_size_rate);
device_printf(devinfo->dev, " IN amp: 0x%08x\n",
devinfo->inamp_cap);
device_printf(devinfo->dev, " OUT amp: 0x%08x\n",
devinfo->outamp_cap);
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL) {
device_printf(devinfo->dev, "Ghost widget nid=%d\n", i);
continue;
}
device_printf(devinfo->dev, "\n");
device_printf(devinfo->dev, " nid: %d%s\n", w->nid,
(w->enable == 0) ? " [DISABLED]" : "");
device_printf(devinfo->dev, " Name: %s\n", w->name);
device_printf(devinfo->dev, " Widget cap: 0x%08x\n",
w->param.widget_cap);
if (w->param.widget_cap & 0x0ee1) {
device_printf(devinfo->dev, " ");
if (HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(w->param.widget_cap))
printf(" LRSWAP");
if (HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(w->param.widget_cap))
printf(" PWR");
if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
printf(" DIGITAL");
if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap))
printf(" UNSOL");
if (HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(w->param.widget_cap))
printf(" PROC");
if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap))
printf(" STRIPE(x%d)",
1 << (fls(w->wclass.conv.stripecap) - 1));
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
if (j == 1)
printf(" STEREO");
else if (j > 1)
printf(" %dCH", j + 1);
printf("\n");
}
if (w->bindas != -1) {
device_printf(devinfo->dev, " Association: %d (0x%08x)\n",
w->bindas, w->bindseqmask);
}
if (w->ossmask != 0 || w->ossdev >= 0) {
device_printf(devinfo->dev, " OSS: %s",
hdaa_audio_ctl_ossmixer_mask2allname(w->ossmask, buf, sizeof(buf)));
if (w->ossdev >= 0)
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
printf(" (%s)", ossnames[w->ossdev]);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
printf("\n");
}
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
hdaa_dump_audio_formats(devinfo->dev,
w->param.supp_stream_formats,
w->param.supp_pcm_size_rate);
} else if (w->type ==
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX || w->waspin)
hdaa_dump_pin(w);
if (w->param.eapdbtl != HDA_INVALID)
device_printf(devinfo->dev, " EAPD: 0x%08x\n",
w->param.eapdbtl);
if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(w->param.widget_cap) &&
w->param.outamp_cap != 0)
hdaa_dump_amp(devinfo->dev, w->param.outamp_cap, "Output");
if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(w->param.widget_cap) &&
w->param.inamp_cap != 0)
hdaa_dump_amp(devinfo->dev, w->param.inamp_cap, " Input");
if (w->nconns > 0) {
device_printf(devinfo->dev, " connections: %d\n", w->nconns);
device_printf(devinfo->dev, " |\n");
}
for (j = 0; j < w->nconns; j++) {
cw = hdaa_widget_get(devinfo, w->conns[j]);
device_printf(devinfo->dev, " + %s<- nid=%d [%s]",
(w->connsenable[j] == 0)?"[DISABLED] ":"",
w->conns[j], (cw == NULL) ? "GHOST!" : cw->name);
if (cw == NULL)
printf(" [UNKNOWN]");
else if (cw->enable == 0)
printf(" [DISABLED]");
if (w->nconns > 1 && w->selconn == j && w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
printf(" (selected)");
printf("\n");
}
}
}
static void
hdaa_dump_dst_nid(struct hdaa_pcm_devinfo *pdevinfo, nid_t nid, int depth)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w, *cw;
char buf[64];
int i, printed = 0;
if (depth > HDA_PARSE_MAXDEPTH)
return;
w = hdaa_widget_get(devinfo, nid);
if (w == NULL || w->enable == 0)
return;
if (depth == 0)
device_printf(pdevinfo->dev, "%*s", 4, "");
else
device_printf(pdevinfo->dev, "%*s + <- ", 4 + (depth - 1) * 7, "");
printf("nid=%d [%s]", w->nid, w->name);
if (depth > 0) {
if (w->ossmask == 0) {
printf("\n");
return;
}
printf(" [src: %s]",
hdaa_audio_ctl_ossmixer_mask2allname(
w->ossmask, buf, sizeof(buf)));
if (w->ossdev >= 0) {
printf("\n");
return;
}
}
printf("\n");
for (i = 0; i < w->nconns; i++) {
if (w->connsenable[i] == 0)
continue;
cw = hdaa_widget_get(devinfo, w->conns[i]);
if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
continue;
if (printed == 0) {
device_printf(pdevinfo->dev, "%*s |\n", 4 + (depth) * 7, "");
printed = 1;
}
hdaa_dump_dst_nid(pdevinfo, w->conns[i], depth + 1);
}
}
static void
hdaa_dump_dac(struct hdaa_pcm_devinfo *pdevinfo)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_audio_as *as;
struct hdaa_widget *w;
int i, printed = 0;
if (pdevinfo->playas < 0)
return;
as = &devinfo->as[pdevinfo->playas];
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
continue;
w = hdaa_widget_get(devinfo, as->pins[i]);
if (w == NULL || w->enable == 0)
continue;
if (printed == 0) {
printed = 1;
device_printf(pdevinfo->dev, "\n");
device_printf(pdevinfo->dev, "Playback:\n");
}
device_printf(pdevinfo->dev, "\n");
hdaa_dump_dst_nid(pdevinfo, as->pins[i], 0);
}
}
static void
hdaa_dump_adc(struct hdaa_pcm_devinfo *pdevinfo)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w;
int i;
int printed = 0;
if (pdevinfo->recas < 0)
return;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
continue;
if (w->bindas != pdevinfo->recas)
continue;
if (printed == 0) {
printed = 1;
device_printf(pdevinfo->dev, "\n");
device_printf(pdevinfo->dev, "Record:\n");
}
device_printf(pdevinfo->dev, "\n");
hdaa_dump_dst_nid(pdevinfo, i, 0);
}
}
static void
hdaa_dump_mix(struct hdaa_pcm_devinfo *pdevinfo)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_widget *w;
int i;
int printed = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0)
continue;
if (w->ossdev != SOUND_MIXER_IMIX)
continue;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (w->bindas != pdevinfo->recas)
continue;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (printed == 0) {
printed = 1;
device_printf(pdevinfo->dev, "\n");
device_printf(pdevinfo->dev, "Input Mix:\n");
}
device_printf(pdevinfo->dev, "\n");
hdaa_dump_dst_nid(pdevinfo, i, 0);
}
}
static void
hdaa_dump_pcmchannels(struct hdaa_pcm_devinfo *pdevinfo)
{
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
nid_t *nids;
int chid, i;
if (pdevinfo->playas >= 0) {
device_printf(pdevinfo->dev, "\n");
device_printf(pdevinfo->dev, "Playback:\n");
device_printf(pdevinfo->dev, "\n");
chid = devinfo->as[pdevinfo->playas].chans[0];
hdaa_dump_audio_formats(pdevinfo->dev,
devinfo->chans[chid].supp_stream_formats,
devinfo->chans[chid].supp_pcm_size_rate);
for (i = 0; i < devinfo->as[pdevinfo->playas].num_chans; i++) {
chid = devinfo->as[pdevinfo->playas].chans[i];
device_printf(pdevinfo->dev, " DAC:");
for (nids = devinfo->chans[chid].io; *nids != -1; nids++)
printf(" %d", *nids);
printf("\n");
}
}
if (pdevinfo->recas >= 0) {
device_printf(pdevinfo->dev, "\n");
device_printf(pdevinfo->dev, "Record:\n");
device_printf(pdevinfo->dev, "\n");
chid = devinfo->as[pdevinfo->recas].chans[0];
hdaa_dump_audio_formats(pdevinfo->dev,
devinfo->chans[chid].supp_stream_formats,
devinfo->chans[chid].supp_pcm_size_rate);
for (i = 0; i < devinfo->as[pdevinfo->recas].num_chans; i++) {
chid = devinfo->as[pdevinfo->recas].chans[i];
device_printf(pdevinfo->dev, " DAC:");
for (nids = devinfo->chans[chid].io; *nids != -1; nids++)
printf(" %d", *nids);
printf("\n");
}
}
}
static void
hdaa_pindump(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_widget *w;
uint32_t res, pincap, delay;
int i;
device_printf(dev, "Dumping AFG pins:\n");
device_printf(dev, "nid 0x as seq "
"device conn jack loc color misc\n");
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
hdaa_dump_pin_config(w, w->wclass.pin.config);
pincap = w->wclass.pin.cap;
device_printf(dev, " Caps: %2s %3s %2s %4s %4s",
HDA_PARAM_PIN_CAP_INPUT_CAP(pincap)?"IN":"",
HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap)?"OUT":"",
HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap)?"HP":"",
HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)?"EAPD":"",
HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)?"VREF":"");
if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap) ||
HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap)) {
if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap)) {
delay = 0;
hda_command(dev,
HDA_CMD_SET_PIN_SENSE(0, w->nid, 0));
do {
res = hda_command(dev,
HDA_CMD_GET_PIN_SENSE(0, w->nid));
if (res != 0x7fffffff && res != 0xffffffff)
break;
DELAY(10);
} while (++delay < 10000);
} else {
delay = 0;
res = hda_command(dev, HDA_CMD_GET_PIN_SENSE(0,
w->nid));
}
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
printf(" Sense: 0x%08x (%sconnected%s)", res,
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
(res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) ?
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
"" : "dis",
(HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap) &&
(res & HDA_CMD_GET_PIN_SENSE_ELD_VALID)) ?
", ELD valid" : "");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (delay > 0)
printf(" delay %dus", delay * 10);
}
printf("\n");
}
device_printf(dev,
"NumGPIO=%d NumGPO=%d NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->gpio_cap),
HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->gpio_cap));
hdaa_dump_gpi(devinfo);
hdaa_dump_gpio(devinfo);
hdaa_dump_gpo(devinfo);
}
static void
hdaa_configure(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_audio_ctl *ctl;
int i;
HDA_BOOTHVERBOSE(
device_printf(dev, "Applying built-in patches...\n");
);
hdaa_patch(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Applying local patches...\n");
);
hdaa_local_patch(devinfo);
hdaa_audio_postprocess(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Parsing Ctls...\n");
);
hdaa_audio_ctl_parse(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling nonaudio...\n");
);
hdaa_audio_disable_nonaudio(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling useless...\n");
);
hdaa_audio_disable_useless(devinfo);
HDA_BOOTVERBOSE(
device_printf(dev, "Patched pins configuration:\n");
hdaa_dump_pin_configs(devinfo);
);
HDA_BOOTHVERBOSE(
device_printf(dev, "Parsing pin associations...\n");
);
hdaa_audio_as_parse(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Building AFG tree...\n");
);
hdaa_audio_build_tree(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling unassociated "
"widgets...\n");
);
hdaa_audio_disable_unas(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling nonselected "
"inputs...\n");
);
hdaa_audio_disable_notselected(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling useless...\n");
);
hdaa_audio_disable_useless(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling "
"crossassociatement connections...\n");
);
hdaa_audio_disable_crossas(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Disabling useless...\n");
);
hdaa_audio_disable_useless(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Binding associations to channels...\n");
);
hdaa_audio_bind_as(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Assigning names to signal sources...\n");
);
hdaa_audio_assign_names(devinfo);
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
HDA_BOOTHVERBOSE(
device_printf(dev, "Preparing PCM devices...\n");
);
hdaa_prepare_pcms(devinfo);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
HDA_BOOTHVERBOSE(
device_printf(dev, "Assigning mixers to the tree...\n");
);
hdaa_audio_assign_mixers(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Preparing pin controls...\n");
);
hdaa_audio_prepare_pin_ctrl(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "AFG commit...\n");
);
hdaa_audio_commit(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Applying direct built-in patches...\n");
);
hdaa_patch_direct(devinfo);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
HDA_BOOTHVERBOSE(
device_printf(dev, "Pin sense init...\n");
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
);
hdaa_sense_init(devinfo);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
HDA_BOOTHVERBOSE(
device_printf(dev, "Creating PCM devices...\n");
);
hdaa_create_pcms(devinfo);
HDA_BOOTVERBOSE(
if (devinfo->quirks != 0) {
device_printf(dev, "FG config/quirks:");
for (i = 0; i < HDAA_QUIRKS_TAB_LEN; i++) {
if ((devinfo->quirks &
hdaa_quirks_tab[i].value) ==
hdaa_quirks_tab[i].value)
printf(" %s", hdaa_quirks_tab[i].key);
}
printf("\n");
}
device_printf(dev, "\n");
device_printf(dev, "+-------------------+\n");
device_printf(dev, "| DUMPING HDA NODES |\n");
device_printf(dev, "+-------------------+\n");
hdaa_dump_nodes(devinfo);
);
HDA_BOOTHVERBOSE(
device_printf(dev, "\n");
device_printf(dev, "+------------------------+\n");
device_printf(dev, "| DUMPING HDA AMPLIFIERS |\n");
device_printf(dev, "+------------------------+\n");
device_printf(dev, "\n");
i = 0;
while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
device_printf(dev, "%3d: nid %3d %s (%s) index %d", i,
(ctl->widget != NULL) ? ctl->widget->nid : -1,
(ctl->ndir == HDAA_CTL_IN)?"in ":"out",
(ctl->dir == HDAA_CTL_IN)?"in ":"out",
ctl->index);
if (ctl->childwidget != NULL)
printf(" cnid %3d", ctl->childwidget->nid);
else
printf(" ");
printf(" ossmask=0x%08x\n",
ctl->ossmask);
device_printf(dev,
" mute: %d step: %3d size: %3d off: %3d%s\n",
ctl->mute, ctl->step, ctl->size, ctl->offset,
(ctl->enable == 0) ? " [DISABLED]" :
((ctl->ossmask == 0) ? " [UNUSED]" : ""));
}
);
HDA_BOOTVERBOSE(
device_printf(dev, "\n");
);
}
static void
hdaa_unconfigure(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_widget *w;
int i, j;
HDA_BOOTHVERBOSE(
device_printf(dev, "Pin sense deinit...\n");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
);
hdaa_sense_deinit(devinfo);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
free(devinfo->ctl, M_HDAA);
devinfo->ctl = NULL;
devinfo->ctlcnt = 0;
free(devinfo->as, M_HDAA);
devinfo->as = NULL;
devinfo->ascnt = 0;
free(devinfo->devs, M_HDAA);
devinfo->devs = NULL;
devinfo->num_devs = 0;
free(devinfo->chans, M_HDAA);
devinfo->chans = NULL;
devinfo->num_chans = 0;
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
continue;
w->enable = 1;
w->selconn = -1;
w->pflags = 0;
w->bindas = -1;
w->bindseqmask = 0;
w->ossdev = -1;
w->ossmask = 0;
for (j = 0; j < w->nconns; j++)
w->connsenable[j] = 1;
Complete rewrite of the snd_hda(4) volume control. Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-22 10:24:12 +00:00
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
w->wclass.pin.config = w->wclass.pin.newconf;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (w->eld != NULL) {
w->eld_len = 0;
free(w->eld, M_HDAA);
w->eld = NULL;
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
static int
hdaa_sysctl_gpi_state(SYSCTL_HANDLER_ARGS)
{
struct hdaa_devinfo *devinfo = oidp->oid_arg1;
device_t dev = devinfo->dev;
char buf[256];
int n = 0, i, numgpi;
uint32_t data = 0;
buf[0] = 0;
hdaa_lock(devinfo);
numgpi = HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap);
if (numgpi > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPI_DATA(0, devinfo->nid));
}
hdaa_unlock(devinfo);
for (i = 0; i < numgpi; i++) {
n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%d",
n != 0 ? " " : "", i, ((data >> i) & 1));
}
return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
}
static int
hdaa_sysctl_gpio_state(SYSCTL_HANDLER_ARGS)
{
struct hdaa_devinfo *devinfo = oidp->oid_arg1;
device_t dev = devinfo->dev;
char buf[256];
int n = 0, i, numgpio;
uint32_t data = 0, enable = 0, dir = 0;
buf[0] = 0;
hdaa_lock(devinfo);
numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
if (numgpio > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
enable = hda_command(dev,
HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
dir = hda_command(dev,
HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
}
hdaa_unlock(devinfo);
for (i = 0; i < numgpio; i++) {
n += snprintf(buf + n, sizeof(buf) - n, "%s%d=",
n != 0 ? " " : "", i);
if ((enable & (1 << i)) == 0) {
n += snprintf(buf + n, sizeof(buf) - n, "disabled");
continue;
}
n += snprintf(buf + n, sizeof(buf) - n, "%sput(%d)",
((dir >> i) & 1) ? "out" : "in", ((data >> i) & 1));
}
return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
}
static int
hdaa_sysctl_gpio_config(SYSCTL_HANDLER_ARGS)
{
struct hdaa_devinfo *devinfo = oidp->oid_arg1;
char buf[256];
int error, n = 0, i, numgpio;
uint32_t gpio, x;
gpio = devinfo->newgpio;
numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
buf[0] = 0;
for (i = 0; i < numgpio; i++) {
x = (gpio & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%s",
n != 0 ? " " : "", i, HDA_GPIO_ACTIONS[x]);
}
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strncmp(buf, "0x", 2) == 0)
gpio = strtol(buf + 2, NULL, 16);
else
gpio = hdaa_gpio_patch(gpio, buf);
hdaa_lock(devinfo);
devinfo->newgpio = devinfo->gpio = gpio;
hdaa_gpio_commit(devinfo);
hdaa_unlock(devinfo);
return (0);
}
static int
hdaa_sysctl_gpo_state(SYSCTL_HANDLER_ARGS)
{
struct hdaa_devinfo *devinfo = oidp->oid_arg1;
device_t dev = devinfo->dev;
char buf[256];
int n = 0, i, numgpo;
uint32_t data = 0;
buf[0] = 0;
hdaa_lock(devinfo);
numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
if (numgpo > 0) {
data = hda_command(dev,
HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
}
hdaa_unlock(devinfo);
for (i = 0; i < numgpo; i++) {
n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%d",
n != 0 ? " " : "", i, ((data >> i) & 1));
}
return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
}
static int
hdaa_sysctl_gpo_config(SYSCTL_HANDLER_ARGS)
{
struct hdaa_devinfo *devinfo = oidp->oid_arg1;
char buf[256];
int error, n = 0, i, numgpo;
uint32_t gpo, x;
gpo = devinfo->newgpo;
numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
buf[0] = 0;
for (i = 0; i < numgpo; i++) {
x = (gpo & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%s",
n != 0 ? " " : "", i, HDA_GPIO_ACTIONS[x]);
}
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strncmp(buf, "0x", 2) == 0)
gpo = strtol(buf + 2, NULL, 16);
else
gpo = hdaa_gpio_patch(gpo, buf);
hdaa_lock(devinfo);
devinfo->newgpo = devinfo->gpo = gpo;
hdaa_gpo_commit(devinfo);
hdaa_unlock(devinfo);
return (0);
}
static int
hdaa_sysctl_reconfig(SYSCTL_HANDLER_ARGS)
{
device_t dev;
struct hdaa_devinfo *devinfo;
int error, val;
dev = oidp->oid_arg1;
devinfo = device_get_softc(dev);
if (devinfo == NULL)
return (EINVAL);
val = 0;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL || val == 0)
return (error);
HDA_BOOTHVERBOSE(
device_printf(dev, "Reconfiguration...\n");
);
if ((error = device_delete_children(dev)) != 0)
return (error);
hdaa_lock(devinfo);
hdaa_unconfigure(dev);
hdaa_configure(dev);
hdaa_unlock(devinfo);
bus_generic_attach(dev);
HDA_BOOTHVERBOSE(
device_printf(dev, "Reconfiguration done\n");
);
return (0);
}
static int
hdaa_suspend(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
int i;
HDA_BOOTHVERBOSE(
device_printf(dev, "Suspend...\n");
);
hdaa_lock(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Stop streams...\n");
);
for (i = 0; i < devinfo->num_chans; i++) {
if (devinfo->chans[i].flags & HDAA_CHN_RUNNING) {
devinfo->chans[i].flags |= HDAA_CHN_SUSPEND;
hdaa_channel_stop(&devinfo->chans[i]);
}
}
HDA_BOOTHVERBOSE(
device_printf(dev, "Power down FG"
" nid=%d to the D3 state...\n",
devinfo->nid);
);
hda_command(devinfo->dev,
HDA_CMD_SET_POWER_STATE(0,
devinfo->nid, HDA_CMD_POWER_STATE_D3));
callout_stop(&devinfo->poll_jack);
hdaa_unlock(devinfo);
callout_drain(&devinfo->poll_jack);
HDA_BOOTHVERBOSE(
device_printf(dev, "Suspend done\n");
);
return (0);
}
static int
hdaa_resume(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
int i;
HDA_BOOTHVERBOSE(
device_printf(dev, "Resume...\n");
);
hdaa_lock(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Power up audio FG nid=%d...\n",
devinfo->nid);
);
hdaa_powerup(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "AFG commit...\n");
);
hdaa_audio_commit(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Applying direct built-in patches...\n");
);
hdaa_patch_direct(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Pin sense init...\n");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
);
hdaa_sense_init(devinfo);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_unlock(devinfo);
for (i = 0; i < devinfo->num_devs; i++) {
struct hdaa_pcm_devinfo *pdevinfo = &devinfo->devs[i];
HDA_BOOTHVERBOSE(
device_printf(pdevinfo->dev,
"OSS mixer reinitialization...\n");
);
if (mixer_reinit(pdevinfo->dev) == -1)
device_printf(pdevinfo->dev,
"unable to reinitialize the mixer\n");
}
hdaa_lock(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Start streams...\n");
);
for (i = 0; i < devinfo->num_chans; i++) {
if (devinfo->chans[i].flags & HDAA_CHN_SUSPEND) {
devinfo->chans[i].flags &= ~HDAA_CHN_SUSPEND;
hdaa_channel_start(&devinfo->chans[i]);
}
}
hdaa_unlock(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Resume done\n");
);
return (0);
}
static int
hdaa_probe(device_t dev)
{
const char *pdesc;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
char buf[128];
if (hda_get_node_type(dev) != HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO)
return (ENXIO);
pdesc = device_get_desc(device_get_parent(dev));
snprintf(buf, sizeof(buf), "%.*s Audio Function Group",
(int)(strlen(pdesc) - 10), pdesc);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
device_set_desc_copy(dev, buf);
return (BUS_PROBE_DEFAULT);
}
static int
hdaa_attach(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
uint32_t res;
nid_t nid = hda_get_node_id(dev);
devinfo->dev = dev;
devinfo->lock = HDAC_GET_MTX(device_get_parent(dev), dev);
devinfo->nid = nid;
devinfo->newquirks = -1;
devinfo->newgpio = -1;
devinfo->newgpo = -1;
callout_init(&devinfo->poll_jack, CALLOUT_MPSAFE);
devinfo->poll_ival = hz;
hdaa_lock(devinfo);
res = hda_command(dev,
HDA_CMD_GET_PARAMETER(0 , nid, HDA_PARAM_SUB_NODE_COUNT));
hdaa_unlock(devinfo);
devinfo->nodecnt = HDA_PARAM_SUB_NODE_COUNT_TOTAL(res);
devinfo->startnode = HDA_PARAM_SUB_NODE_COUNT_START(res);
devinfo->endnode = devinfo->startnode + devinfo->nodecnt;
HDA_BOOTVERBOSE(
device_printf(dev, "Subsystem ID: 0x%08x\n",
hda_get_subsystem_id(dev));
);
HDA_BOOTHVERBOSE(
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
device_printf(dev,
"Audio Function Group at nid=%d: %d subnodes %d-%d\n",
nid, devinfo->nodecnt,
devinfo->startnode, devinfo->endnode - 1);
);
if (devinfo->nodecnt > 0)
devinfo->widget = (struct hdaa_widget *)malloc(
sizeof(*(devinfo->widget)) * devinfo->nodecnt, M_HDAA,
M_WAITOK | M_ZERO);
else
devinfo->widget = NULL;
hdaa_lock(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Powering up...\n");
);
hdaa_powerup(devinfo);
HDA_BOOTHVERBOSE(
device_printf(dev, "Parsing audio FG...\n");
);
hdaa_audio_parse(devinfo);
HDA_BOOTVERBOSE(
device_printf(dev, "Original pins configuration:\n");
hdaa_dump_pin_configs(devinfo);
);
hdaa_configure(dev);
hdaa_unlock(devinfo);
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
&devinfo->newquirks, sizeof(&devinfo->newquirks),
hdaa_sysctl_quirks, "A", "Configuration options");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"gpi_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
devinfo, sizeof(devinfo),
hdaa_sysctl_gpi_state, "A", "GPI state");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"gpio_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
devinfo, sizeof(devinfo),
hdaa_sysctl_gpio_state, "A", "GPIO state");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"gpio_config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
devinfo, sizeof(devinfo),
hdaa_sysctl_gpio_config, "A", "GPIO configuration");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"gpo_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
devinfo, sizeof(devinfo),
hdaa_sysctl_gpo_state, "A", "GPO state");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"gpo_config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
devinfo, sizeof(devinfo),
hdaa_sysctl_gpo_config, "A", "GPO configuration");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
"reconfig", CTLTYPE_INT | CTLFLAG_RW,
dev, sizeof(dev),
hdaa_sysctl_reconfig, "I", "Reprocess configuration");
bus_generic_attach(dev);
return (0);
}
static int
hdaa_detach(device_t dev)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
int error;
if ((error = device_delete_children(dev)) != 0)
return (error);
hdaa_lock(devinfo);
hdaa_unconfigure(dev);
devinfo->poll_ival = 0;
callout_stop(&devinfo->poll_jack);
hdaa_unlock(devinfo);
callout_drain(&devinfo->poll_jack);
free(devinfo->widget, M_HDAA);
return (0);
}
static int
hdaa_print_child(device_t dev, device_t child)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_pcm_devinfo *pdevinfo =
(struct hdaa_pcm_devinfo *)device_get_ivars(child);
struct hdaa_audio_as *as;
int retval, first = 1, i;
retval = bus_print_child_header(dev, child);
retval += printf(" at nid ");
if (pdevinfo->playas >= 0) {
as = &devinfo->as[pdevinfo->playas];
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
continue;
retval += printf("%s%d", first ? "" : ",", as->pins[i]);
first = 0;
}
}
if (pdevinfo->recas >= 0) {
if (pdevinfo->playas >= 0) {
retval += printf(" and ");
first = 1;
}
as = &devinfo->as[pdevinfo->recas];
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
continue;
retval += printf("%s%d", first ? "" : ",", as->pins[i]);
first = 0;
}
}
retval += bus_print_child_footer(dev, child);
return (retval);
}
static int
hdaa_child_location_str(device_t dev, device_t child, char *buf,
size_t buflen)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_pcm_devinfo *pdevinfo =
(struct hdaa_pcm_devinfo *)device_get_ivars(child);
struct hdaa_audio_as *as;
int first = 1, i, len = 0;
len += snprintf(buf + len, buflen - len, "nid=");
if (pdevinfo->playas >= 0) {
as = &devinfo->as[pdevinfo->playas];
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
continue;
len += snprintf(buf + len, buflen - len,
"%s%d", first ? "" : ",", as->pins[i]);
first = 0;
}
}
if (pdevinfo->recas >= 0) {
as = &devinfo->as[pdevinfo->recas];
for (i = 0; i < 16; i++) {
if (as->pins[i] <= 0)
continue;
len += snprintf(buf + len, buflen - len,
"%s%d", first ? "" : ",", as->pins[i]);
first = 0;
}
}
return (0);
}
static void
hdaa_stream_intr(device_t dev, int dir, int stream)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
struct hdaa_chan *ch;
int i;
for (i = 0; i < devinfo->num_chans; i++) {
ch = &devinfo->chans[i];
if (!(ch->flags & HDAA_CHN_RUNNING))
continue;
if (ch->dir == ((dir == 1) ? PCMDIR_PLAY : PCMDIR_REC) &&
ch->sid == stream) {
hdaa_unlock(devinfo);
chn_intr(ch->c);
hdaa_lock(devinfo);
}
}
}
static void
hdaa_unsol_intr(device_t dev, uint32_t resp)
{
struct hdaa_devinfo *devinfo = device_get_softc(dev);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
struct hdaa_widget *w;
int i, tag, flags;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
HDA_BOOTHVERBOSE(
device_printf(dev, "Unsolicited response %08x\n", resp);
);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
tag = resp >> 26;
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL || w->enable == 0 || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
if (w->unsol != tag)
continue;
if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap) ||
HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
flags = resp & 0x03;
else
flags = 0x01;
if (flags & 0x01)
hdaa_presence_handler(w);
Improve HDMI/DisplayPort audio support in snd_hda(4): - Enable and handle unsolicited responses from digital display pins, reporting connection and EDID-Like Data (ELD) validity status changes. - Fetch ELD data, describing connected digital display device audio capabilities. These data not really used at the moment (user is not denied to use audio formats not supported by the device), only printed to verbose logs. But they are useful for debugging. The fact that ELD was received tells that HDMI link was established and video driver enabled HDMI audio passthrough. Some old chips may not return ELD, so lack of it is not necessary a problem. - Add some more points to CODEC configuration sequence: - For converter widgets, supporting more then two channels (HDMI/DP converter widgets support 8), set number of channels to handle. - For digital display pins (HDMI/DP) fill audio infoframe, reporting connected device about number of channels and speakers allocation. - For digital display pins (HDMI/DP) set mapping between channels seen by software and channels transferred via HDMI/DisplayPort. - Allow more audio formats, not used for analog connections because of stereo pairs orientation, but easily applicable to HDMI/DisplayPort: 2.1, 3.0, 3.1, 4.1, 5.0, 6.0, 6.1, 7.0. That list may be filtered later using info from ELD. - Disable MSI interrupts for NVIDIA HDA controllers before GT520. At this point I can successfully play audio over HDMI from NVIDIA GT210 and GT520 cards with nvidia-driver-290.10 driver to Marantz SR4001 receiver in 2.0, 2.1, 3.0, 4.0, 4.1, 5.0 and 5.1 PCM formats at 44, 48, 88 and 96KHz at 16 and 24 bits, same as do AC3/DTS passthrough. 6.0, 6.1, 7.0 and 7.1 PCM formats are not working for me, but I think it is because of receiver age. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-18 19:12:33 +00:00
if (flags & 0x02)
hdaa_eld_handler(w);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
}
static device_method_t hdaa_methods[] = {
/* device interface */
DEVMETHOD(device_probe, hdaa_probe),
DEVMETHOD(device_attach, hdaa_attach),
DEVMETHOD(device_detach, hdaa_detach),
DEVMETHOD(device_suspend, hdaa_suspend),
DEVMETHOD(device_resume, hdaa_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, hdaa_print_child),
DEVMETHOD(bus_child_location_str, hdaa_child_location_str),
DEVMETHOD(hdac_stream_intr, hdaa_stream_intr),
DEVMETHOD(hdac_unsol_intr, hdaa_unsol_intr),
DEVMETHOD(hdac_pindump, hdaa_pindump),
{ 0, 0 }
};
static driver_t hdaa_driver = {
"hdaa",
hdaa_methods,
sizeof(struct hdaa_devinfo),
};
static devclass_t hdaa_devclass;
DRIVER_MODULE(snd_hda, hdacc, hdaa_driver, hdaa_devclass, 0, 0);
static void
hdaa_chan_formula(struct hdaa_devinfo *devinfo, int asid,
char *buf, int buflen)
{
struct hdaa_audio_as *as;
int c;
as = &devinfo->as[asid];
c = devinfo->chans[as->chans[0]].channels;
if (c == 1)
snprintf(buf, buflen, "mono");
else if (c == 2) {
if (as->hpredir < 0)
buf[0] = 0;
else
snprintf(buf, buflen, "2.0");
} else if (as->pinset == 0x0003)
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
snprintf(buf, buflen, "3.1");
else if (as->pinset == 0x0005 || as->pinset == 0x0011)
snprintf(buf, buflen, "4.0");
else if (as->pinset == 0x0007 || as->pinset == 0x0013)
snprintf(buf, buflen, "5.1");
else if (as->pinset == 0x0017)
snprintf(buf, buflen, "7.1");
else
snprintf(buf, buflen, "%dch", c);
if (as->hpredir >= 0)
strlcat(buf, "+HP", buflen);
}
static int
hdaa_chan_type(struct hdaa_devinfo *devinfo, int asid)
{
struct hdaa_audio_as *as;
struct hdaa_widget *w;
int i, t = -1, t1;
as = &devinfo->as[asid];
for (i = 0; i < 16; i++) {
w = hdaa_widget_get(devinfo, as->pins[i]);
if (w == NULL || w->enable == 0 || w->type !=
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
continue;
t1 = HDA_CONFIG_DEFAULTCONF_DEVICE(w->wclass.pin.config);
if (t == -1)
t = t1;
else if (t != t1) {
t = -2;
break;
}
}
return (t);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
static int
hdaa_sysctl_32bit(SYSCTL_HANDLER_ARGS)
{
struct hdaa_audio_as *as = (struct hdaa_audio_as *)oidp->oid_arg1;
struct hdaa_pcm_devinfo *pdevinfo = as->pdevinfo;
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_chan *ch;
int error, val, i;
uint32_t pcmcap;
ch = &devinfo->chans[as->chans[0]];
val = (ch->bit32 == 4) ? 32 : ((ch->bit32 == 3) ? 24 :
((ch->bit32 == 2) ? 20 : 0));
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
pcmcap = ch->supp_pcm_size_rate;
if (val == 32 && HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(pcmcap))
ch->bit32 = 4;
else if (val == 24 && HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(pcmcap))
ch->bit32 = 3;
else if (val == 20 && HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap))
ch->bit32 = 2;
else
return (EINVAL);
for (i = 1; i < as->num_chans; i++)
devinfo->chans[as->chans[i]].bit32 = ch->bit32;
return (0);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
static int
hdaa_pcm_probe(device_t dev)
{
struct hdaa_pcm_devinfo *pdevinfo =
(struct hdaa_pcm_devinfo *)device_get_ivars(dev);
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
const char *pdesc;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
char chans1[8], chans2[8];
char buf[128];
int loc1, loc2, t1, t2;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (pdevinfo->playas >= 0)
loc1 = devinfo->as[pdevinfo->playas].location;
else
loc1 = devinfo->as[pdevinfo->recas].location;
if (pdevinfo->recas >= 0)
loc2 = devinfo->as[pdevinfo->recas].location;
else
loc2 = loc1;
if (loc1 != loc2)
loc1 = -2;
if (loc1 >= 0 && HDA_LOCS[loc1][0] == '0')
loc1 = -2;
chans1[0] = 0;
chans2[0] = 0;
t1 = t2 = -1;
if (pdevinfo->playas >= 0) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_chan_formula(devinfo, pdevinfo->playas,
chans1, sizeof(chans1));
t1 = hdaa_chan_type(devinfo, pdevinfo->playas);
}
if (pdevinfo->recas >= 0) {
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
hdaa_chan_formula(devinfo, pdevinfo->recas,
chans2, sizeof(chans2));
t2 = hdaa_chan_type(devinfo, pdevinfo->recas);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (chans1[0] != 0 || chans2[0] != 0) {
if (chans1[0] == 0 && pdevinfo->playas >= 0)
snprintf(chans1, sizeof(chans1), "2.0");
else if (chans2[0] == 0 && pdevinfo->recas >= 0)
snprintf(chans2, sizeof(chans2), "2.0");
if (strcmp(chans1, chans2) == 0)
chans2[0] = 0;
}
if (t1 == -1)
t1 = t2;
else if (t2 == -1)
t2 = t1;
if (t1 != t2)
t1 = -2;
if (pdevinfo->digital)
t1 = -2;
pdesc = device_get_desc(device_get_parent(dev));
snprintf(buf, sizeof(buf), "%.*s (%s%s%s%s%s%s%s%s%s)",
(int)(strlen(pdesc) - 21), pdesc,
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
loc1 >= 0 ? HDA_LOCS[loc1] : "", loc1 >= 0 ? " " : "",
(pdevinfo->digital == 0x7)?"HDMI/DP":
((pdevinfo->digital == 0x5)?"DisplayPort":
((pdevinfo->digital == 0x3)?"HDMI":
((pdevinfo->digital)?"Digital":"Analog"))),
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
chans1[0] ? " " : "", chans1,
chans2[0] ? "/" : "", chans2,
t1 >= 0 ? " " : "", t1 >= 0 ? HDA_DEVS[t1] : "");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
device_set_desc_copy(dev, buf);
return (BUS_PROBE_SPECIFIC);
}
static int
hdaa_pcm_attach(device_t dev)
{
struct hdaa_pcm_devinfo *pdevinfo =
(struct hdaa_pcm_devinfo *)device_get_ivars(dev);
struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
struct hdaa_audio_as *as;
struct snddev_info *d;
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
char status[SND_STATUSLEN];
int i;
pdevinfo->chan_size = pcm_getbuffersize(dev,
HDA_BUFSZ_MIN, HDA_BUFSZ_DEFAULT, HDA_BUFSZ_MAX);
HDA_BOOTVERBOSE(
device_printf(dev, "+--------------------------------------+\n");
device_printf(dev, "| DUMPING PCM Playback/Record Channels |\n");
device_printf(dev, "+--------------------------------------+\n");
hdaa_dump_pcmchannels(pdevinfo);
device_printf(dev, "\n");
device_printf(dev, "+-------------------------------+\n");
device_printf(dev, "| DUMPING Playback/Record Paths |\n");
device_printf(dev, "+-------------------------------+\n");
hdaa_dump_dac(pdevinfo);
hdaa_dump_adc(pdevinfo);
hdaa_dump_mix(pdevinfo);
device_printf(dev, "\n");
device_printf(dev, "+-------------------------+\n");
device_printf(dev, "| DUMPING Volume Controls |\n");
device_printf(dev, "+-------------------------+\n");
hdaa_dump_ctls(pdevinfo, "Master Volume", SOUND_MASK_VOLUME);
hdaa_dump_ctls(pdevinfo, "PCM Volume", SOUND_MASK_PCM);
hdaa_dump_ctls(pdevinfo, "CD Volume", SOUND_MASK_CD);
hdaa_dump_ctls(pdevinfo, "Microphone Volume", SOUND_MASK_MIC);
hdaa_dump_ctls(pdevinfo, "Microphone2 Volume", SOUND_MASK_MONITOR);
hdaa_dump_ctls(pdevinfo, "Line-in Volume", SOUND_MASK_LINE);
hdaa_dump_ctls(pdevinfo, "Speaker/Beep Volume", SOUND_MASK_SPEAKER);
hdaa_dump_ctls(pdevinfo, "Recording Level", SOUND_MASK_RECLEV);
hdaa_dump_ctls(pdevinfo, "Input Mix Level", SOUND_MASK_IMIX);
hdaa_dump_ctls(pdevinfo, "Input Monitoring Level", SOUND_MASK_IGAIN);
hdaa_dump_ctls(pdevinfo, NULL, 0);
device_printf(dev, "\n");
);
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
i &= HDA_BLK_ALIGN;
if (i < HDA_BLK_MIN)
i = HDA_BLK_MIN;
pdevinfo->chan_blkcnt = pdevinfo->chan_size / i;
i = 0;
while (pdevinfo->chan_blkcnt >> i)
i++;
pdevinfo->chan_blkcnt = 1 << (i - 1);
if (pdevinfo->chan_blkcnt < HDA_BDL_MIN)
pdevinfo->chan_blkcnt = HDA_BDL_MIN;
else if (pdevinfo->chan_blkcnt > HDA_BDL_MAX)
pdevinfo->chan_blkcnt = HDA_BDL_MAX;
} else
pdevinfo->chan_blkcnt = HDA_BDL_DEFAULT;
/*
* We don't register interrupt handler with snd_setup_intr
* in pcm device. Mark pcm device as MPSAFE manually.
*/
pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
HDA_BOOTHVERBOSE(
device_printf(dev, "OSS mixer initialization...\n");
);
if (mixer_init(dev, &hdaa_audio_ctl_ossmixer_class, pdevinfo) != 0)
device_printf(dev, "Can't register mixer\n");
HDA_BOOTHVERBOSE(
device_printf(dev, "Registering PCM channels...\n");
);
if (pcm_register(dev, pdevinfo, (pdevinfo->playas >= 0)?1:0,
(pdevinfo->recas >= 0)?1:0) != 0)
device_printf(dev, "Can't register PCM\n");
pdevinfo->registered++;
d = device_get_softc(dev);
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
if (pdevinfo->playas >= 0) {
as = &devinfo->as[pdevinfo->playas];
for (i = 0; i < as->num_chans; i++)
pcm_addchan(dev, PCMDIR_PLAY, &hdaa_channel_class,
&devinfo->chans[as->chans[i]]);
SYSCTL_ADD_PROC(&d->play_sysctl_ctx,
SYSCTL_CHILDREN(d->play_sysctl_tree), OID_AUTO,
"32bit", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
as, sizeof(as), hdaa_sysctl_32bit, "I",
"Resolution of 32bit samples (20/24/32bit)");
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
if (pdevinfo->recas >= 0) {
as = &devinfo->as[pdevinfo->recas];
for (i = 0; i < as->num_chans; i++)
pcm_addchan(dev, PCMDIR_REC, &hdaa_channel_class,
&devinfo->chans[as->chans[i]]);
SYSCTL_ADD_PROC(&d->rec_sysctl_ctx,
SYSCTL_CHILDREN(d->rec_sysctl_tree), OID_AUTO,
"32bit", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
as, sizeof(as), hdaa_sysctl_32bit, "I",
"Resolution of 32bit samples (20/24/32bit)");
pdevinfo->autorecsrc = 2;
resource_int_value(device_get_name(dev), device_get_unit(dev),
"rec.autosrc", &pdevinfo->autorecsrc);
SYSCTL_ADD_INT(&d->rec_sysctl_ctx,
SYSCTL_CHILDREN(d->rec_sysctl_tree), OID_AUTO,
"autosrc", CTLTYPE_INT | CTLFLAG_RW,
&pdevinfo->autorecsrc, 0,
"Automatic recording source selection");
}
if (pdevinfo->mixer != NULL) {
hdaa_audio_ctl_set_defaults(pdevinfo);
if (pdevinfo->recas >= 0) {
as = &devinfo->as[pdevinfo->recas];
hdaa_lock(devinfo);
hdaa_autorecsrc_handler(as, NULL);
hdaa_unlock(devinfo);
}
Major snd_hda driver rewrite: - Huge old hdac driver was split into three independent pieces: HDA controller driver (hdac), HDA CODEC driver (hdacc) and HDA sudio function driver (hdaa). - Support for multichannel recording was added. Now, as specification defines, driver checks input associations for pins with sequence numbers 14 and 15, and if found (usually) -- works as before, mixing signals together. If it doesn't, it configures input association as multichannel. - Signal tracer was improved to look for cases where several DACs/ADCs in CODEC can work with the same audio signal. If such case found, driver registers additional playback/record stream (channel) for the pcm device. - New controller streams reservation mechanism was implemented. That allows to have more pcm devices then streams supported by the controller (usually 4 in each direction). Now it limits only number of simultaneously transferred audio streams, that is rarely reachable and properly reported if happens. - Codec pins and GPIO signals configuration was exported via set of writable sysctls. Another sysctl dev.hdaa.X.reconfig allows to trigger driver reconfiguration in run-time. - Driver now decodes pins location and connector type names. In some cases it allows to hint user where on the system case connectors, related to the pcm device, are located. Number of channels supported by pcm device, reported now (if it is not 2), should also make search easier. - Added workaround for digital mic on some Asus laptops/netbooks. MFC after: 2 months Sponsored by: iXsystems, Inc.
2012-01-15 13:21:36 +00:00
}
snprintf(status, SND_STATUSLEN, "on %s %s",
device_get_nameunit(device_get_parent(dev)),
PCM_KLDSTRING(snd_hda));
pcm_setstatus(dev, status);
return (0);
}
static int
hdaa_pcm_detach(device_t dev)
{
struct hdaa_pcm_devinfo *pdevinfo =
(struct hdaa_pcm_devinfo *)device_get_ivars(dev);
int err;
if (pdevinfo->registered > 0) {
err = pcm_unregister(dev);
if (err != 0)
return (err);
}
return (0);
}
static device_method_t hdaa_pcm_methods[] = {
/* device interface */
DEVMETHOD(device_probe, hdaa_pcm_probe),
DEVMETHOD(device_attach, hdaa_pcm_attach),
DEVMETHOD(device_detach, hdaa_pcm_detach),
{ 0, 0 }
};
static driver_t hdaa_pcm_driver = {
"pcm",
hdaa_pcm_methods,
PCM_SOFTC_SIZE,
};
DRIVER_MODULE(snd_hda_pcm, hdaa, hdaa_pcm_driver, pcm_devclass, 0, 0);
MODULE_DEPEND(snd_hda, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(snd_hda, 1);