|
Packit |
427e91 |
/* Copyright 2011 David Henningsson, Canonical Ltd.
|
|
Packit |
427e91 |
License: GPLv2+
|
|
Packit |
427e91 |
*/
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
#include <stdlib.h>
|
|
Packit |
427e91 |
#include <string.h>
|
|
Packit |
427e91 |
#include "sysfs-pin-configs.h"
|
|
Packit |
427e91 |
#include "apply-changes.h"
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
const gchar *hint_names[25] = {
|
|
Packit |
427e91 |
"jack_detect", "inv_jack_detect", "trigger_sense", "inv_eapd",
|
|
Packit |
427e91 |
"pcm_format_first", "sticky_stream", "spdif_status_reset",
|
|
Packit |
427e91 |
"pin_amp_workaround", "single_adc_amp", "auto_mute", "auto_mic",
|
|
Packit |
427e91 |
"line_in_auto_switch", "auto_mute_via_amp", "need_dac_fix", "primary_hp",
|
|
Packit |
427e91 |
"multi_io", "multi_cap_vol", "inv_dmic_split", "indep_hp",
|
|
Packit |
427e91 |
"add_stereo_mix_input", "add_jack_modes", "power_down_unused", "add_hp_mic",
|
|
Packit |
427e91 |
"hp_mic_detect", NULL };
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
const gchar** get_standard_hint_names()
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return hint_names;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
int get_codec_name_list(codec_name_t* names, int entries)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
GDir* sysdir = g_dir_open("/sys/class/sound", 0, NULL);
|
|
Packit |
427e91 |
int count = 0;
|
|
Packit |
427e91 |
if (!sysdir)
|
|
Packit |
427e91 |
return 0;
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
while (entries > 1) {
|
|
Packit |
427e91 |
gchar** cd = NULL;
|
|
Packit |
427e91 |
gboolean ok;
|
|
Packit |
427e91 |
const gchar* dirname = g_dir_read_name(sysdir);
|
|
Packit |
427e91 |
if (!dirname)
|
|
Packit |
427e91 |
break;
|
|
Packit |
427e91 |
/* Split e g "hwC0D1" into "hw", "0" and "1" */
|
|
Packit |
427e91 |
cd = g_strsplit_set(dirname, "CD", 9);
|
|
Packit |
427e91 |
ok = g_strv_length(cd) == 3;
|
|
Packit |
427e91 |
ok &= strcmp(cd[0], "hw") == 0;
|
|
Packit |
427e91 |
if (ok) {
|
|
Packit |
427e91 |
gchar* filetest = g_strdup_printf("/sys/class/sound/%s/init_pin_configs", dirname);
|
|
Packit |
427e91 |
ok = g_file_test(filetest, G_FILE_TEST_IS_REGULAR);
|
|
Packit |
427e91 |
g_free(filetest);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
if (ok) {
|
|
Packit |
427e91 |
gchar* chip_name = NULL, *vendor_name = NULL;
|
|
Packit |
427e91 |
gchar* chip_file = g_strdup_printf("/sys/class/sound/%s/chip_name", dirname);
|
|
Packit |
427e91 |
gchar* vendor_file = g_strdup_printf("/sys/class/sound/%s/vendor_name", dirname);
|
|
Packit |
427e91 |
ok = g_file_get_contents(chip_file, &chip_name, NULL, NULL);
|
|
Packit |
427e91 |
ok &= g_file_get_contents(vendor_file, &vendor_name, NULL, NULL);
|
|
Packit |
427e91 |
if (ok) {
|
|
Packit |
427e91 |
names->name = g_strdup_printf("%s %s", g_strchomp(vendor_name), g_strchomp(chip_name));
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_free(chip_name);
|
|
Packit |
427e91 |
g_free(vendor_name);
|
|
Packit |
427e91 |
g_free(chip_file);
|
|
Packit |
427e91 |
g_free(vendor_file);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
if (ok) {
|
|
Packit |
427e91 |
names->card = atoi(cd[1]);
|
|
Packit |
427e91 |
names->device = atoi(cd[2]);
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
names++;
|
|
Packit |
427e91 |
count++;
|
|
Packit |
427e91 |
entries--;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_strfreev(cd);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
if (entries) {
|
|
Packit |
427e91 |
names->name = NULL;
|
|
Packit |
427e91 |
names->card = -1;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_dir_close(sysdir);
|
|
Packit |
427e91 |
return count;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static unsigned long read_header_value(gchar* contents, gchar* key)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* s = strstr(contents, key);
|
|
Packit |
427e91 |
s += strlen(key);
|
|
Packit |
427e91 |
return g_ascii_strtoull(s, NULL, 0);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
void get_codec_header(int card, int device, unsigned int* address,
|
|
Packit |
427e91 |
unsigned int* codec_vendorid, unsigned int* codec_ssid)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* filename = g_strdup_printf("/proc/asound/card%d/codec#%d", card, device);
|
|
Packit |
427e91 |
gchar* contents = NULL;
|
|
Packit |
427e91 |
int ok = g_file_get_contents(filename, &contents, NULL, NULL);
|
|
Packit |
427e91 |
g_free(filename);
|
|
Packit |
427e91 |
if (!ok)
|
|
Packit |
427e91 |
return;
|
|
Packit |
427e91 |
*address = read_header_value(contents, "Address: ");
|
|
Packit |
427e91 |
*codec_vendorid = read_header_value(contents, "Vendor Id: ");
|
|
Packit |
427e91 |
*codec_ssid = read_header_value(contents, "Subsystem Id: ");
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
g_free(contents);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static void get_pin_caps(pin_configs_t* pins, int entries, int card, int device)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* filename = g_strdup_printf("/proc/asound/card%d/codec#%d", card, device);
|
|
Packit |
427e91 |
gchar* contents = NULL;
|
|
Packit |
427e91 |
int ok = g_file_get_contents(filename, &contents, NULL, NULL);
|
|
Packit |
427e91 |
g_free(filename);
|
|
Packit |
427e91 |
if (!ok)
|
|
Packit |
427e91 |
return;
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
for (; entries; entries--, pins++) {
|
|
Packit |
427e91 |
gchar* nodestr = g_strdup_printf("Node 0x%02x [", pins->nid);
|
|
Packit |
427e91 |
gchar* q = strstr(contents, nodestr);
|
|
Packit |
427e91 |
g_free(nodestr);
|
|
Packit |
427e91 |
if (!q)
|
|
Packit |
427e91 |
continue;
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
q = strstr(q, "wcaps 0x");
|
|
Packit |
427e91 |
if (!q)
|
|
Packit |
427e91 |
continue;
|
|
Packit |
427e91 |
q += strlen("wcaps ");
|
|
Packit |
427e91 |
pins->wid_caps = g_ascii_strtoull(q, NULL, 0);
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
q = strstr(q, "Pincap 0x");
|
|
Packit |
427e91 |
if (!q)
|
|
Packit |
427e91 |
continue;
|
|
Packit |
427e91 |
q += strlen("Pincap ");
|
|
Packit |
427e91 |
pins->pin_caps = g_ascii_strtoull(q, NULL, 0);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_free(contents);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
gchar *get_hint_overrides(int card, int device)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* filename = g_strdup_printf("/sys/class/sound/hwC%dD%d/hints", card, device);
|
|
Packit |
427e91 |
gchar* contents = NULL;
|
|
Packit |
427e91 |
int ok = g_file_get_contents(filename, &contents, NULL, NULL);
|
|
Packit |
427e91 |
g_free(filename);
|
|
Packit |
427e91 |
if (!ok)
|
|
Packit |
427e91 |
return NULL;
|
|
Packit |
427e91 |
return contents;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static void read_pin_overrides(pin_configs_t* pins, int entries, int card, int device, gboolean is_user)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* filename = g_strdup_printf("/sys/class/sound/hwC%dD%d/%s_pin_configs", card, device, is_user ? "user" : "driver");
|
|
Packit |
427e91 |
gchar* contents = NULL;
|
|
Packit |
427e91 |
gchar** lines = NULL, **line_iterator;
|
|
Packit |
427e91 |
int count = 0;
|
|
Packit |
427e91 |
int ok = g_file_get_contents(filename, &contents, NULL, NULL);
|
|
Packit |
427e91 |
g_free(filename);
|
|
Packit |
427e91 |
if (!ok)
|
|
Packit |
427e91 |
return;
|
|
Packit |
427e91 |
line_iterator = lines = g_strsplit(contents, "\n", entries);
|
|
Packit |
427e91 |
while (count < entries && *line_iterator) {
|
|
Packit |
427e91 |
gchar** line = g_strsplit(*line_iterator, " ", 0);
|
|
Packit |
427e91 |
line_iterator++;
|
|
Packit |
427e91 |
if (g_strv_length(line) == 2) {
|
|
Packit |
427e91 |
int nid = g_ascii_strtoull(line[0], NULL, 0) & 0xff;
|
|
Packit |
427e91 |
unsigned long config = g_ascii_strtoull(line[1], NULL, 0);
|
|
Packit |
427e91 |
int i;
|
|
Packit |
427e91 |
for (i=0; i < entries; i++)
|
|
Packit |
427e91 |
if (nid == pins[i].nid) {
|
|
Packit |
427e91 |
if (is_user) {
|
|
Packit |
427e91 |
pins[i].user_override = FALSE;
|
|
Packit |
427e91 |
pins[i].user_override = config != actual_pin_config(&pins[i]);
|
|
Packit |
427e91 |
pins[i].user_pin_config = config;
|
|
Packit |
427e91 |
} else {
|
|
Packit |
427e91 |
pins[i].driver_override = config != pins[i].init_pin_config;
|
|
Packit |
427e91 |
pins[i].driver_pin_config = config;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_strfreev(line);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_strfreev(lines);
|
|
Packit |
427e91 |
g_free(contents);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
int get_pin_configs_list(pin_configs_t* pins, int entries, int card, int device)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
gchar* filename = g_strdup_printf("/sys/class/sound/hwC%dD%d/init_pin_configs", card, device);
|
|
Packit |
427e91 |
gchar* contents = NULL;
|
|
Packit |
427e91 |
gchar** lines = NULL, **line_iterator;
|
|
Packit |
427e91 |
int count = 0;
|
|
Packit |
427e91 |
int ok = g_file_get_contents(filename, &contents, NULL, NULL);
|
|
Packit |
427e91 |
g_free(filename);
|
|
Packit |
427e91 |
if (!ok)
|
|
Packit |
427e91 |
return 0;
|
|
Packit |
427e91 |
line_iterator = lines = g_strsplit(contents, "\n", entries);
|
|
Packit |
427e91 |
g_free(contents);
|
|
Packit |
427e91 |
while (count < entries && *line_iterator) {
|
|
Packit |
427e91 |
gchar** line = g_strsplit(*line_iterator, " ", 0);
|
|
Packit |
427e91 |
line_iterator++;
|
|
Packit |
427e91 |
if (g_strv_length(line) == 2) {
|
|
Packit |
427e91 |
pins[count].nid = g_ascii_strtoull(line[0], NULL, 0);
|
|
Packit |
427e91 |
pins[count].init_pin_config = g_ascii_strtoull(line[1], NULL, 0) & 0xffffffff;
|
|
Packit |
427e91 |
pins[count].driver_override = FALSE;
|
|
Packit |
427e91 |
pins[count].user_override = FALSE;
|
|
Packit |
427e91 |
count++;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_strfreev(line);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
g_strfreev(lines);
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
read_pin_overrides(pins, count, card, device, FALSE);
|
|
Packit |
427e91 |
read_pin_overrides(pins, count, card, device, TRUE);
|
|
Packit |
427e91 |
get_pin_caps(pins, count, card, device);
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
return count;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
unsigned long actual_pin_config(pin_configs_t* pins)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
if (pins->user_override)
|
|
Packit |
427e91 |
return pins->user_pin_config;
|
|
Packit |
427e91 |
if (pins->driver_override)
|
|
Packit |
427e91 |
return pins->driver_pin_config;
|
|
Packit |
427e91 |
return pins->init_pin_config;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
/*** Code below taken from sound/pci/hda/hda_proc.c and hda_codec.h, (C) Takashi Iwai, GPLv2+. ****/
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
#define u32 unsigned long
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
#define AC_WCAP_STEREO (1<<0) /* stereo I/O */
|
|
Packit |
427e91 |
#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */
|
|
Packit |
427e91 |
#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */
|
|
Packit |
427e91 |
#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */
|
|
Packit |
427e91 |
#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */
|
|
Packit |
427e91 |
#define AC_WCAP_STRIPE (1<<5) /* stripe */
|
|
Packit |
427e91 |
#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */
|
|
Packit |
427e91 |
#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */
|
|
Packit |
427e91 |
#define AC_WCAP_CONN_LIST (1<<8) /* connection list */
|
|
Packit |
427e91 |
#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
|
|
Packit |
427e91 |
#define AC_WCAP_POWER (1<<10) /* power control */
|
|
Packit |
427e91 |
#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
|
|
Packit |
427e91 |
#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
|
|
Packit |
427e91 |
#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
|
|
Packit |
427e91 |
#define AC_WCAP_DELAY (0xf<<16)
|
|
Packit |
427e91 |
#define AC_WCAP_DELAY_SHIFT 16
|
|
Packit |
427e91 |
#define AC_WCAP_TYPE (0xf<<20)
|
|
Packit |
427e91 |
#define AC_WCAP_TYPE_SHIFT 20
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
|
|
Packit |
427e91 |
#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_OUT (1<<4) /* output capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_IN (1<<5) /* input capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */
|
|
Packit |
427e91 |
/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification,
|
|
Packit |
427e91 |
* but is marked reserved in the Intel HDA specification.
|
|
Packit |
427e91 |
*/
|
|
Packit |
427e91 |
#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
|
|
Packit |
427e91 |
/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
|
|
Packit |
427e91 |
* in HD-audio specification
|
|
Packit |
427e91 |
*/
|
|
Packit |
427e91 |
#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
|
|
Packit |
427e91 |
#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can
|
|
Packit |
427e91 |
* coexist with AC_PINCAP_HDMI
|
|
Packit |
427e91 |
*/
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF (0x37<<8)
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_SHIFT 8
|
|
Packit |
427e91 |
#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
|
|
Packit |
427e91 |
#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */
|
|
Packit |
427e91 |
/* Vref status (used in pin cap) */
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_50 (1<<1) /* 50% */
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_GRD (1<<2) /* ground */
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_80 (1<<4) /* 80% */
|
|
Packit |
427e91 |
#define AC_PINCAP_VREF_100 (1<<5) /* 100% */
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
/* configuration default - 32bit */
|
|
Packit |
427e91 |
#define AC_DEFCFG_SEQUENCE (0xf<<0)
|
|
Packit |
427e91 |
#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
|
|
Packit |
427e91 |
#define AC_DEFCFG_ASSOC_SHIFT 4
|
|
Packit |
427e91 |
#define AC_DEFCFG_MISC (0xf<<8)
|
|
Packit |
427e91 |
#define AC_DEFCFG_MISC_SHIFT 8
|
|
Packit |
427e91 |
#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
|
|
Packit |
427e91 |
#define AC_DEFCFG_COLOR (0xf<<12)
|
|
Packit |
427e91 |
#define AC_DEFCFG_COLOR_SHIFT 12
|
|
Packit |
427e91 |
#define AC_DEFCFG_CONN_TYPE (0xf<<16)
|
|
Packit |
427e91 |
#define AC_DEFCFG_CONN_TYPE_SHIFT 16
|
|
Packit |
427e91 |
#define AC_DEFCFG_DEVICE (0xf<<20)
|
|
Packit |
427e91 |
#define AC_DEFCFG_DEVICE_SHIFT 20
|
|
Packit |
427e91 |
#define AC_DEFCFG_LOCATION (0x3f<<24)
|
|
Packit |
427e91 |
#define AC_DEFCFG_LOCATION_SHIFT 24
|
|
Packit |
427e91 |
#define AC_DEFCFG_GROSSLOC (0x3<<28)
|
|
Packit |
427e91 |
#define AC_DEFCFG_GROSSLOC_SHIFT 28
|
|
Packit |
427e91 |
#define AC_DEFCFG_PORT_CONN (0x3<<30)
|
|
Packit |
427e91 |
#define AC_DEFCFG_PORT_CONN_SHIFT 30
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static const char *get_jack_color(u32 cfg)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
static char *names[16] = {
|
|
Packit |
427e91 |
"", "Black", "Grey", "Blue",
|
|
Packit |
427e91 |
"Green", "Red", "Orange", "Yellow",
|
|
Packit |
427e91 |
"Purple", "Pink", NULL, NULL,
|
|
Packit |
427e91 |
NULL, NULL, "White", "Other",
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
|
|
Packit |
427e91 |
if (names[cfg])
|
|
Packit |
427e91 |
return names[cfg];
|
|
Packit |
427e91 |
else
|
|
Packit |
427e91 |
return "UNKNOWN";
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static const char *get_jack_type(u32 cfg)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
static char *jack_types[16] = {
|
|
Packit |
427e91 |
"Line Out", "Speaker", "Headphone", "CD",
|
|
Packit |
427e91 |
"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
|
|
Packit |
427e91 |
"Line In", "Aux", "Mic", "Telephony",
|
|
Packit |
427e91 |
"SPDIF In", "Digital In", "Reserved", "Other"
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
return jack_types[(cfg & AC_DEFCFG_DEVICE)
|
|
Packit |
427e91 |
>> AC_DEFCFG_DEVICE_SHIFT];
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static const char *get_jack_location(u32 cfg)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
static char *bases[7] = {
|
|
Packit |
427e91 |
"", ", Rear side", ", Front side", ", Left side", ", Right side", ", Top", ", Bottom",
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
static unsigned char specials_idx[] = {
|
|
Packit |
427e91 |
0x07, 0x08,
|
|
Packit |
427e91 |
0x17, 0x18, 0x19,
|
|
Packit |
427e91 |
0x37, 0x38
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
static char *specials[] = {
|
|
Packit |
427e91 |
", Rear Panel", ", Drive Bar",
|
|
Packit |
427e91 |
", Riser", ", HDMI", ", ATAPI",
|
|
Packit |
427e91 |
", Mobile-In", ", Mobile-Out"
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
int i;
|
|
Packit |
427e91 |
cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
|
|
Packit |
427e91 |
if ((cfg & 0x0f) < 7)
|
|
Packit |
427e91 |
return bases[cfg & 0x0f];
|
|
Packit |
427e91 |
for (i = 0; i < 7; i++) {
|
|
Packit |
427e91 |
if (cfg == specials_idx[i])
|
|
Packit |
427e91 |
return specials[i];
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
return "UNKNOWN";
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
/**** Borrowed code end *****/
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t pc_arr[] = {
|
|
Packit |
427e91 |
{"Not connected", 1 << AC_DEFCFG_PORT_CONN_SHIFT},
|
|
Packit |
427e91 |
{"Jack", 0},
|
|
Packit |
427e91 |
{"Internal", 2 << AC_DEFCFG_PORT_CONN_SHIFT},
|
|
Packit |
427e91 |
{"Both", 3 << AC_DEFCFG_PORT_CONN_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t location_arr[] = {
|
|
Packit |
427e91 |
{"External", 0},
|
|
Packit |
427e91 |
{"Rear", 1 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Front", 2 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Left", 3 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Right", 4 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Top", 5 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Bottom", 6 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Rear panel", 7 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Drive bay", 8 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
{"Internal", 16 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Internal riser", (16+7) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Internal display", (16+8) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Internal ATAPI", (16+9) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
{"Dock", 32 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Rear", 33 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Front", 34 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Left", 35 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Right", 36 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Top", 37 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Dock Bottom", 38 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
{"Other", 48 << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Other bottom", (48+7) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Inside mobile lid", (48+8) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
{"Outside mobile lid", (48+9) << AC_DEFCFG_LOCATION_SHIFT},
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t device_arr[] = {
|
|
Packit |
427e91 |
{"Line Out", 0},
|
|
Packit |
427e91 |
{"Speaker", 1 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Headphone", 2 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"CD", 3 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"SPDIF Out", 4 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Digital Out", 5 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Modem (Line side)", 6 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Modem (Handset side)", 7 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Line In", 8 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Aux", 9 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Microphone", 10 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Telephony", 11 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"SPDIF In", 12 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Other Digital In", 13 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{"Other", 15 << AC_DEFCFG_DEVICE_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t jack_arr[] = {
|
|
Packit |
427e91 |
{"Unknown", 0},
|
|
Packit |
427e91 |
{"3.5 mm", 1 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"6.3 mm", 2 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"ATAPI", 3 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"RCA", 4 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"Optical", 5 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"Other Digital", 6 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"Other Analog", 7 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"DIN", 8 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"XLR", 9 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"RJ-11 (Modem)", 10 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"Combination", 11 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{"Other", 15 << AC_DEFCFG_CONN_TYPE_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t color_arr[] = {
|
|
Packit |
427e91 |
{"Unknown", 0},
|
|
Packit |
427e91 |
{"Black", 1 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Grey", 2 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Blue", 3 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Green", 4 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Red", 5 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Orange", 6 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Yellow", 7 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Purple", 8 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Pink", 9 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"White", 14 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{"Other", 15 << AC_DEFCFG_COLOR_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t no_presence_arr[] = {
|
|
Packit |
427e91 |
{"Present", 0},
|
|
Packit |
427e91 |
{"Not present", 1 << AC_DEFCFG_MISC_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t group_nr_arr[] = {
|
|
Packit |
427e91 |
{"1", 1 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"2", 2 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"3", 3 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"4", 4 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"5", 5 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"6", 6 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"7", 7 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"8", 8 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"9", 9 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"10", 10 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"11", 11 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"12", 12 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"13", 13 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"14", 14 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{"15", 15 << AC_DEFCFG_ASSOC_SHIFT},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t channel_arr[] = {
|
|
Packit |
427e91 |
{"Front", 0},
|
|
Packit |
427e91 |
{"Center/LFE", 1},
|
|
Packit |
427e91 |
{"Back", 2},
|
|
Packit |
427e91 |
{"Side", 3},
|
|
Packit |
427e91 |
{"Channel 8 & 9", 4},
|
|
Packit |
427e91 |
{"Channel 10 & 11", 5},
|
|
Packit |
427e91 |
{"Channel 12 & 13", 6},
|
|
Packit |
427e91 |
{"Channel 14 & 15", 7},
|
|
Packit |
427e91 |
{"Channel 16 & 17", 8},
|
|
Packit |
427e91 |
{"Channel 18 & 19", 9},
|
|
Packit |
427e91 |
{"Channel 20 & 21", 10},
|
|
Packit |
427e91 |
{"Channel 22 & 23", 11},
|
|
Packit |
427e91 |
{"Channel 24 & 25", 12},
|
|
Packit |
427e91 |
{"Channel 26 & 27", 13},
|
|
Packit |
427e91 |
{"Channel 28 & 29", 14},
|
|
Packit |
427e91 |
{"Channel 30 & 31", 15},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static free_override_t* type_order[FREE_OVERRIDES_COUNT] = {
|
|
Packit |
427e91 |
pc_arr, location_arr, device_arr, jack_arr,
|
|
Packit |
427e91 |
color_arr, no_presence_arr, group_nr_arr, channel_arr
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
unsigned long get_free_override_mask(int type)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
static unsigned long masks[FREE_OVERRIDES_COUNT] = {
|
|
Packit |
427e91 |
AC_DEFCFG_PORT_CONN,
|
|
Packit |
427e91 |
AC_DEFCFG_LOCATION,
|
|
Packit |
427e91 |
AC_DEFCFG_DEVICE,
|
|
Packit |
427e91 |
AC_DEFCFG_CONN_TYPE,
|
|
Packit |
427e91 |
AC_DEFCFG_COLOR,
|
|
Packit |
427e91 |
AC_DEFCFG_MISC & (AC_DEFCFG_MISC_NO_PRESENCE << AC_DEFCFG_MISC_SHIFT),
|
|
Packit |
427e91 |
AC_DEFCFG_DEF_ASSOC,
|
|
Packit |
427e91 |
AC_DEFCFG_SEQUENCE,
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
return masks[type];
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
free_override_t* get_free_override_list(int type)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return type_order[type];
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
int get_port_conn(unsigned long config)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return (config & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
gchar* get_config_description(unsigned long config)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int port_conn = get_port_conn(config);
|
|
Packit |
427e91 |
if (port_conn == 1)
|
|
Packit |
427e91 |
return g_strdup("Not connected");
|
|
Packit |
427e91 |
return g_strdup_printf("%s %s%s%s", port_conn == 2 ? "Internal" : get_jack_color(config),
|
|
Packit |
427e91 |
get_jack_type(config),
|
|
Packit |
427e91 |
((config >> (AC_DEFCFG_LOCATION_SHIFT+4)) & 3) == 2 ? ", Docking station" : "",
|
|
Packit |
427e91 |
get_jack_location(config));
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
/*
|
|
Packit |
427e91 |
gchar* get_caps_description(unsigned long pin_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int vref = (pin_caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
|
|
Packit |
427e91 |
gboolean linein = (pin_caps & AC_PINCAP_IN) && (vref & AC_PINCAP_VREF_HIZ);
|
|
Packit |
427e91 |
gboolean lineout = pin_caps & AC_PINCAP_OUT;
|
|
Packit |
427e91 |
gboolean hp = pin_caps & AC_PINCAP_HP_DRV;
|
|
Packit |
427e91 |
gboolean mic = (pin_caps & AC_PINCAP_IN) && (vref & AC_PINCAP_VREF_50 || vref & AC_PINCAP_VREF_80);
|
|
Packit |
427e91 |
return g_strjoin("",
|
|
Packit |
427e91 |
lineout ? ", Line out": "",
|
|
Packit |
427e91 |
hp ? ", Headphone": "",
|
|
Packit |
427e91 |
linein ? ", Line in": "",
|
|
Packit |
427e91 |
mic ? ", Microphone": "", NULL);
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
*/
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean extmic_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int vref = (pin_caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_IN) && (vref & AC_PINCAP_VREF_50 || vref & AC_PINCAP_VREF_80);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean headphone_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return pin_caps & AC_PINCAP_HP_DRV;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean lineout_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_OUT) && !(wid_caps & AC_WCAP_DIGITAL);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean spdifout_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_OUT) && (wid_caps & AC_WCAP_DIGITAL) && !(pin_caps & AC_PINCAP_HDMI);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean hdmi_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return pin_caps & AC_PINCAP_HDMI;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean intmic_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_IN) && !(wid_caps & AC_WCAP_DIGITAL);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean spdifin_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_IN) && (wid_caps & AC_WCAP_DIGITAL);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean linein_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int vref = (pin_caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
|
|
Packit |
427e91 |
return (pin_caps & AC_PINCAP_IN) && (vref & AC_PINCAP_VREF_HIZ);
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static gboolean disabled_caps(unsigned long pin_caps, unsigned long wid_caps)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
return TRUE;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
#define DEFAULT_MASK (AC_DEFCFG_PORT_CONN | AC_DEFCFG_GROSSLOC | AC_DEFCFG_DEVICE)
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
static typical_pins_t simple_typical_pins[] = {
|
|
Packit |
427e91 |
{"Headphone", headphone_caps, 0x0321403f, DEFAULT_MASK, },
|
|
Packit |
427e91 |
{"Microphone", extmic_caps, 0x03a19020, DEFAULT_MASK,},
|
|
Packit |
427e91 |
{"Line out (Front)", lineout_caps, 0x01014010, DEFAULT_MASK | AC_DEFCFG_SEQUENCE,},
|
|
Packit |
427e91 |
{"Line out (Center/LFE)", lineout_caps, 0x01014011, DEFAULT_MASK | AC_DEFCFG_SEQUENCE,},
|
|
Packit |
427e91 |
{"Line out (Back)", lineout_caps, 0x01014012, DEFAULT_MASK | AC_DEFCFG_SEQUENCE,},
|
|
Packit |
427e91 |
{"Line out (Side)", lineout_caps, 0x01014013, DEFAULT_MASK | AC_DEFCFG_SEQUENCE,},
|
|
Packit |
427e91 |
{"Line in", linein_caps, 0x0181304f, DEFAULT_MASK,},
|
|
Packit |
427e91 |
{"Internal speaker", lineout_caps, 0x90170150, DEFAULT_MASK | AC_DEFCFG_SEQUENCE, },
|
|
Packit |
427e91 |
{"Internal speaker (LFE)", lineout_caps, 0x90170151, DEFAULT_MASK | AC_DEFCFG_SEQUENCE, },
|
|
Packit |
427e91 |
{"Internal speaker (Back)", lineout_caps, 0x90170152, DEFAULT_MASK | AC_DEFCFG_SEQUENCE, },
|
|
Packit |
427e91 |
{"Internal mic", intmic_caps, 0x90a60160, DEFAULT_MASK,},
|
|
Packit |
427e91 |
{"HDMI / DisplayPort", hdmi_caps, 0x18560070, AC_DEFCFG_PORT_CONN | AC_DEFCFG_LOCATION,},
|
|
Packit |
427e91 |
{"SPDIF out", spdifout_caps, 0x014b1180, AC_DEFCFG_PORT_CONN | AC_DEFCFG_DEVICE,},
|
|
Packit |
427e91 |
{"SPDIF in", spdifin_caps, 0x01cb6190, AC_DEFCFG_PORT_CONN | AC_DEFCFG_DEVICE,},
|
|
Packit |
427e91 |
{"Dock Headphone", headphone_caps, 0x222140af, DEFAULT_MASK, },
|
|
Packit |
427e91 |
{"Dock Microphone", extmic_caps, 0x22a190a0, DEFAULT_MASK,},
|
|
Packit |
427e91 |
{"Dock Line out", lineout_caps, 0x220140b0, DEFAULT_MASK | AC_DEFCFG_SEQUENCE,},
|
|
Packit |
427e91 |
{"Dock Line in", linein_caps, 0x228130bf, DEFAULT_MASK,},
|
|
Packit |
427e91 |
{"Not connected", disabled_caps, 0x40f000f0, AC_DEFCFG_PORT_CONN,},
|
|
Packit |
427e91 |
{}
|
|
Packit |
427e91 |
};
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
int get_typical_pins(typical_pins_t* result, int entries, pin_configs_t* pin_cfg, int caps_limit)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int count = 0;
|
|
Packit |
427e91 |
int index = -1;
|
|
Packit |
427e91 |
unsigned long actual = actual_pin_config(pin_cfg);
|
|
Packit |
427e91 |
typical_pins_t* src;
|
|
Packit |
427e91 |
for (src = simple_typical_pins; src->name && entries; src++) {
|
|
Packit |
427e91 |
if (caps_limit && !src->caps_limit(pin_cfg->pin_caps, pin_cfg->wid_caps))
|
|
Packit |
427e91 |
continue;
|
|
Packit |
427e91 |
if ((actual & src->match_mask) == (src->pin_set & src->match_mask))
|
|
Packit |
427e91 |
index = count;
|
|
Packit |
427e91 |
*result = *src;
|
|
Packit |
427e91 |
result++;
|
|
Packit |
427e91 |
count++;
|
|
Packit |
427e91 |
entries--;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
if (entries) {
|
|
Packit |
427e91 |
result->name = NULL;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
return index;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
gboolean find_pin_channel_match(pin_configs_t* pins, int count, unsigned long pinval)
|
|
Packit |
427e91 |
{
|
|
Packit |
427e91 |
int i;
|
|
Packit |
427e91 |
pinval &= (AC_DEFCFG_DEF_ASSOC + AC_DEFCFG_SEQUENCE);
|
|
Packit |
427e91 |
for (i = 0; i < count; i++, pins++) {
|
|
Packit |
427e91 |
unsigned long val2 = actual_pin_config(pins);
|
|
Packit |
427e91 |
if (get_port_conn(val2) == 1)
|
|
Packit |
427e91 |
continue;
|
|
Packit |
427e91 |
if (pinval == (val2 & (AC_DEFCFG_DEF_ASSOC + AC_DEFCFG_SEQUENCE)))
|
|
Packit |
427e91 |
return TRUE;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
return FALSE;
|
|
Packit |
427e91 |
}
|
|
Packit |
427e91 |
|
|
Packit |
427e91 |
|