Merge remote-tracking branch 'asoc/fix/fsl' into asoc-linus

This commit is contained in:
Mark Brown
2013-09-11 11:17:15 +01:00
63 changed files with 2174 additions and 5017 deletions
@@ -0,0 +1,34 @@
Freescale i.MX audio complex with S/PDIF transceiver
Required properties:
- compatible : "fsl,imx-audio-spdif"
- model : The user-visible name of this sound complex
- spdif-controller : The phandle of the i.MX S/PDIF controller
Optional properties:
- spdif-out : This is a boolean property. If present, the transmitting
function of S/PDIF will be enabled, indicating there's a physical
S/PDIF out connector/jack on the board or it's connecting to some
other IP block, such as an HDMI encoder/display-controller.
- spdif-in : This is a boolean property. If present, the receiving
function of S/PDIF will be enabled, indicating there's a physical
S/PDIF in connector/jack on the board.
* Note: At least one of these two properties should be set in the DT binding.
Example:
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
spdif-controller = <&spdif>;
spdif-out;
spdif-in;
};
@@ -0,0 +1,29 @@
* mvebu (Kirkwood, Dove, Armada 370) audio controller
Required properties:
- compatible: "marvell,mvebu-audio"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: list of two irq numbers.
The first irq is used for data flow and the second one is used for errors.
- clocks: one or two phandles.
The first one is mandatory and defines the internal clock.
The second one is optional and defines an external clock.
- clock-names: names associated to the clocks:
"internal" for the internal clock
"extclk" for the external clock
Example:
i2s1: audio-controller@b4000 {
compatible = "marvell,mvebu-audio";
reg = <0xb4000 0x2210>;
interrupts = <21>, <22>;
clocks = <&gate_clk 13>;
clock-names = "internal";
};
@@ -244,6 +244,7 @@ STAC9227/9228/9229/927x
5stack-no-fp D965 5stack without front panel
dell-3stack Dell Dimension E520
dell-bios Fixes with Dell BIOS setup
dell-bios-amic Fixes with Dell BIOS setup including analog mic
volknob Fixes with volume-knob widget 0x24
auto BIOS setup (default)
+2
View File
@@ -454,6 +454,8 @@ The generic parser supports the following hints:
- need_dac_fix (bool): limits the DACs depending on the channel count
- primary_hp (bool): probe headphone jacks as the primary outputs;
default true
- multi_io (bool): try probing multi-I/O config (e.g. shared
line-in/surround, mic/clfe jacks)
- multi_cap_vol (bool): provide multiple capture volumes
- inv_dmic_split (bool): provide split internal mic volume/switch for
phase-inverted digital mics
+11
View File
@@ -7676,6 +7676,17 @@ F: include/sound/
F: include/uapi/sound/
F: sound/
SOUND - COMPRESSED AUDIO
M: Vinod Koul <vinod.koul@intel.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
S: Supported
F: Documentation/sound/alsa/compress_offload.txt
F: include/sound/compress_driver.h
F: include/uapi/sound/compress_*
F: sound/core/compress_offload.c
F: sound/soc/soc-compress.c
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
+11 -2
View File
@@ -82,7 +82,8 @@ static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param)
static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
{
struct cb_data *data;
int len = (param->cap == DMA_CYCLIC) ? param->period : param->len;
dma_addr_t pos = param->buf;
dma_addr_t end = param->buf + param->len;
list_for_each_entry(data, &dma_list, node)
if (data->ch == ch)
@@ -94,7 +95,15 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
data->fp_param = param->fp_param;
}
s3c2410_dma_enqueue(ch, (void *)data, param->buf, len);
if (param->cap != DMA_CYCLIC) {
s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len);
return 0;
}
while (pos < end) {
s3c2410_dma_enqueue(ch, (void *)data, pos, param->period);
pos += param->period;
}
return 0;
}
+8
View File
@@ -27,6 +27,7 @@
#include <linux/rwsem.h> /* struct rw_semaphore */
#include <linux/pm.h> /* pm_message_t */
#include <linux/stringify.h>
#include <linux/printk.h>
/* number of supported soundcards */
#ifdef CONFIG_SND_DYNAMIC_MINORS
@@ -375,6 +376,11 @@ void __snd_printk(unsigned int level, const char *file, int line,
*/
#define snd_BUG() WARN(1, "BUG?\n")
/**
* Suppress high rates of output when CONFIG_SND_DEBUG is enabled.
*/
#define snd_printd_ratelimit() printk_ratelimit()
/**
* snd_BUG_ON - debugging check macro
* @cond: condition to evaluate
@@ -398,6 +404,8 @@ static inline void _snd_printd(int level, const char *format, ...) {}
unlikely(__ret_warn_on); \
})
static inline bool snd_printd_ratelimit(void) { return false; }
#endif /* CONFIG_SND_DEBUG */
#ifdef CONFIG_SND_DEBUG_VERBOSE
+1 -1
View File
@@ -413,7 +413,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
struct snd_soc_dapm_widget *sink);
/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
+4 -4
View File
@@ -697,7 +697,6 @@ struct snd_soc_codec {
unsigned int probed:1; /* Codec has been probed */
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
unsigned int cache_init:1; /* codec cache has been initialized */
unsigned int using_regmap:1; /* using regmap access */
u32 cache_only; /* Suppress writes to hardware */
@@ -705,7 +704,6 @@ struct snd_soc_codec {
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
enum snd_soc_control_type control_type;
hw_write_t hw_write;
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
@@ -724,7 +722,6 @@ struct snd_soc_codec {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root;
struct dentry *debugfs_reg;
struct dentry *debugfs_dapm;
#endif
};
@@ -849,7 +846,6 @@ struct snd_soc_platform {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_platform_root;
struct dentry *debugfs_dapm;
#endif
};
@@ -934,6 +930,10 @@ struct snd_soc_dai_link {
/* machine stream operations */
const struct snd_soc_ops *ops;
const struct snd_soc_compr_ops *compr_ops;
/* For unidirectional dai links */
bool playback_only;
bool capture_only;
};
struct snd_soc_codec_conf {
+1 -1
View File
@@ -111,7 +111,7 @@ struct hdspm_ltc {
enum hdspm_ltc_input_format input_format;
};
#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_mixer_ioctl)
#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc)
/**
* The status data reflects the device's current state
+2 -2
View File
@@ -184,7 +184,7 @@ static void xrun(struct snd_pcm_substream *substream)
do { \
if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
xrun_log_show(substream); \
if (printk_ratelimit()) { \
if (snd_printd_ratelimit()) { \
snd_printd("PCM: " fmt, ##args); \
} \
dump_stack_on_xrun(substream); \
@@ -342,7 +342,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
return -EPIPE;
}
if (pos >= runtime->buffer_size) {
if (printk_ratelimit()) {
if (snd_printd_ratelimit()) {
char name[16];
snd_pcm_debug_name(substream, name, sizeof(name));
xrun_log_show(substream);
+1 -1
View File
@@ -1022,7 +1022,7 @@ static void dummy_proc_write(struct snd_info_entry *entry,
if (i >= ARRAY_SIZE(fields))
continue;
snd_info_get_str(item, ptr, sizeof(item));
if (strict_strtoull(item, 0, &val))
if (kstrtoull(item, 0, &val))
continue;
if (fields[i].size == sizeof(int))
*get_dummy_int_ptr(dummy, fields[i].offset) = val;
+1 -3
View File
@@ -49,7 +49,6 @@ struct fwspk {
struct snd_card *card;
struct fw_unit *unit;
const struct device_info *device_info;
struct snd_pcm_substream *pcm;
struct mutex mutex;
struct cmp_connection connection;
struct amdtp_out_stream stream;
@@ -363,8 +362,7 @@ static int fwspk_create_pcm(struct fwspk *fwspk)
return err;
pcm->private_data = fwspk;
strcpy(pcm->name, fwspk->device_info->short_name);
fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
fwspk->pcm->ops = &ops;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
return 0;
}
+1 -2
View File
@@ -443,8 +443,7 @@ static void snd_interwave_detect_memory(struct snd_gus_card *gus)
for (i = 0; i < 8; ++i)
iwave[i] = snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM
printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos,
8, iwave);
printk(KERN_DEBUG "ROM at 0x%06x = %8phC\n", bank_pos, iwave);
#endif
if (strncmp(iwave, "INTRWAVE", 8))
continue; /* first check */
+1 -2
View File
@@ -557,7 +557,6 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
unsigned long flags;
int err = 0, n = 0;
struct dma_buffparms *dmap = adev->dmap_in;
int go;
if (!(adev->open_mode & OPEN_READ))
return -EIO;
@@ -584,7 +583,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
spin_unlock_irqrestore(&dmap->lock,flags);
return -EAGAIN;
}
if ((go = adev->go))
if (adev->go)
timeout = dmabuf_timeout(dmap);
spin_unlock_irqrestore(&dmap->lock,flags);
+2 -7
View File
@@ -152,14 +152,9 @@ config SND_HDA_CODEC_HDMI
This module is automatically loaded at probing.
config SND_HDA_I915
bool "Build Display HD-audio controller/codec power well support for i915 cards"
bool
default y
depends on DRM_I915
help
Say Y here to include full HDMI and DisplayPort HD-audio controller/codec
power-well support for Intel Haswell graphics cards based on the i915 driver.
Note that this option must be enabled for Intel Haswell C+ stepping machines, otherwise
the GPU audio controller/codecs will not be initialized or damaged when exit from S3 mode.
config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support"
+62 -2
View File
@@ -666,6 +666,64 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
}
EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
/* return DEVLIST_LEN parameter of the given widget */
static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
{
unsigned int wcaps = get_wcaps(codec, nid);
unsigned int parm;
if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
get_wcaps_type(wcaps) != AC_WID_PIN)
return 0;
parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
if (parm == -1 && codec->bus->rirb_error)
parm = 0;
return parm & AC_DEV_LIST_LEN_MASK;
}
/**
* snd_hda_get_devices - copy device list without cache
* @codec: the HDA codec
* @nid: NID of the pin to parse
* @dev_list: device list array
* @max_devices: max. number of devices to store
*
* Copy the device list. This info is dynamic and so not cached.
* Currently called only from hda_proc.c, so not exported.
*/
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
u8 *dev_list, int max_devices)
{
unsigned int parm;
int i, dev_len, devices;
parm = get_num_devices(codec, nid);
if (!parm) /* not multi-stream capable */
return 0;
dev_len = parm + 1;
dev_len = dev_len < max_devices ? dev_len : max_devices;
devices = 0;
while (devices < dev_len) {
parm = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_DEVICE_LIST, devices);
if (parm == -1 && codec->bus->rirb_error)
break;
for (i = 0; i < 8; i++) {
dev_list[devices] = (u8)parm;
parm >>= 4;
devices++;
if (devices >= dev_len)
break;
}
}
return devices;
}
/**
* snd_hda_queue_unsol_event - add an unsolicited event to queue
* @bus: the BUS
@@ -1216,11 +1274,13 @@ static void hda_jackpoll_work(struct work_struct *work)
{
struct hda_codec *codec =
container_of(work, struct hda_codec, jackpoll_work.work);
if (!codec->jackpoll_interval)
return;
snd_hda_jack_set_dirty_all(codec);
snd_hda_jack_poll_all(codec);
if (!codec->jackpoll_interval)
return;
queue_delayed_work(codec->bus->workq, &codec->jackpoll_work,
codec->jackpoll_interval);
}
+21
View File
@@ -94,6 +94,8 @@ enum {
#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
#define AC_VERB_GET_DEVICE_SEL 0xf35
#define AC_VERB_GET_DEVICE_LIST 0xf36
/*
* SET verbs
@@ -133,6 +135,7 @@ enum {
#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
#define AC_VERB_SET_HDMI_CP_CTRL 0x733
#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
#define AC_VERB_SET_DEVICE_SEL 0x735
/*
* Parameter IDs
@@ -154,6 +157,7 @@ enum {
#define AC_PAR_GPIO_CAP 0x11
#define AC_PAR_AMP_OUT_CAP 0x12
#define AC_PAR_VOL_KNB_CAP 0x13
#define AC_PAR_DEVLIST_LEN 0x15
#define AC_PAR_HDMI_LPCM_CAP 0x20
/*
@@ -251,6 +255,11 @@ enum {
#define AC_UNSOL_RES_TAG_SHIFT 26
#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
#define AC_UNSOL_RES_SUBTAG_SHIFT 21
#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry
* (for DP1.2 MST)
*/
#define AC_UNSOL_RES_DE_SHIFT 15
#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */
#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
@@ -352,6 +361,10 @@ enum {
#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
/* Display pin's device list length */
#define AC_DEV_LIST_LEN_MASK 0x3f
#define AC_MAX_DEV_LIST_LEN 64
/*
* Control Parameters
*/
@@ -460,6 +473,11 @@ enum {
#define AC_DEFCFG_PORT_CONN (0x3<<30)
#define AC_DEFCFG_PORT_CONN_SHIFT 30
/* Display pin's device list entry */
#define AC_DE_PD (1<<0)
#define AC_DE_ELDV (1<<1)
#define AC_DE_IA (1<<2)
/* device device types (0x0-0xf) */
enum {
AC_JACK_LINE_OUT,
@@ -885,6 +903,7 @@ struct hda_codec {
unsigned int pcm_format_first:1; /* PCM format must be set first */
unsigned int epss:1; /* supporting EPSS? */
unsigned int cached_write:1; /* write only to caches */
unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
#ifdef CONFIG_PM
unsigned int power_on :1; /* current (global) power-state */
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
@@ -972,6 +991,8 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
const hda_nid_t *list);
int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t nid, int recursive);
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
u8 *dev_list, int max_devices);
int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
+63 -16
View File
@@ -142,6 +142,9 @@ static void parse_user_hints(struct hda_codec *codec)
val = snd_hda_get_bool_hint(codec, "primary_hp");
if (val >= 0)
spec->no_primary_hp = !val;
val = snd_hda_get_bool_hint(codec, "multi_io");
if (val >= 0)
spec->no_multi_io = !val;
val = snd_hda_get_bool_hint(codec, "multi_cap_vol");
if (val >= 0)
spec->multi_cap_vol = !!val;
@@ -813,6 +816,8 @@ static void resume_path_from_idx(struct hda_codec *codec, int path_idx)
static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
enum {
HDA_CTL_WIDGET_VOL,
@@ -830,7 +835,13 @@ static const struct snd_kcontrol_new control_templates[] = {
.put = hda_gen_mixer_mute_put, /* replaced */
.private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
},
HDA_BIND_MUTE(NULL, 0, 0, 0),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = snd_hda_mixer_amp_switch_info,
.get = snd_hda_mixer_bind_switch_get,
.put = hda_gen_bind_mute_put, /* replaced */
.private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
},
};
/* add dynamic controls from template */
@@ -937,8 +948,8 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
}
/* playback mute control with the software mute bit check */
static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
static void sync_auto_mute_bits(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct hda_gen_spec *spec = codec->spec;
@@ -949,10 +960,22 @@ static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] &= enabled;
ucontrol->value.integer.value[1] &= enabled;
}
}
static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
sync_auto_mute_bits(kcontrol, ucontrol);
return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
}
static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
sync_auto_mute_bits(kcontrol, ucontrol);
return snd_hda_mixer_bind_switch_put(kcontrol, ucontrol);
}
/* any ctl assigned to the path with the given index? */
static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
{
@@ -1541,7 +1564,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
cfg->speaker_pins,
spec->multiout.extra_out_nid,
spec->speaker_paths);
if (fill_mio_first && cfg->line_outs == 1 &&
if (!spec->no_multi_io &&
fill_mio_first && cfg->line_outs == 1 &&
cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
err = fill_multi_ios(codec, cfg->line_out_pins[0], true);
if (!err)
@@ -1554,7 +1578,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
spec->private_dac_nids, spec->out_paths,
spec->main_out_badness);
if (fill_mio_first &&
if (!spec->no_multi_io && fill_mio_first &&
cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
/* try to fill multi-io first */
err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
@@ -1582,7 +1606,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
return err;
badness += err;
}
if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
if (!spec->no_multi_io &&
cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
if (err < 0)
return err;
@@ -1600,7 +1625,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
check_aamix_out_path(codec, spec->speaker_paths[0]);
}
if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
if (!spec->no_multi_io &&
cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2)
spec->multi_ios = 1; /* give badness */
@@ -3724,7 +3750,8 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
/* check each pin in the given array; returns true if any of them is plugged */
static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
{
int i, present = 0;
int i;
bool present = false;
for (i = 0; i < num_pins; i++) {
hda_nid_t nid = pins[i];
@@ -3733,14 +3760,15 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
/* don't detect pins retasked as inputs */
if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
continue;
present |= snd_hda_jack_detect(codec, nid);
if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
present = true;
}
return present;
}
/* standard HP/line-out auto-mute helper */
static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
bool mute)
int *paths, bool mute)
{
struct hda_gen_spec *spec = codec->spec;
int i;
@@ -3752,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
break;
if (spec->auto_mute_via_amp) {
struct nid_path *path;
hda_nid_t mute_nid;
path = snd_hda_get_path_from_idx(codec, paths[i]);
if (!path)
continue;
mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]);
if (!mute_nid)
continue;
if (mute)
spec->mute_bits |= (1ULL << nid);
spec->mute_bits |= (1ULL << mute_nid);
else
spec->mute_bits &= ~(1ULL << nid);
spec->mute_bits &= ~(1ULL << mute_nid);
set_pin_eapd(codec, nid, !mute);
continue;
}
@@ -3786,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
void snd_hda_gen_update_outputs(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
int *paths;
int on;
/* Control HP pins/amps depending on master_mute state;
* in general, HP pins/amps control should be enabled in all cases,
* but currently set only for master_mute, just to be safe
*/
if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
paths = spec->out_paths;
else
paths = spec->hp_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins, spec->master_mute);
spec->autocfg.hp_pins, paths, spec->master_mute);
if (!spec->automute_speaker)
on = 0;
@@ -3801,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
on = spec->hp_jack_present | spec->line_jack_present;
on |= spec->master_mute;
spec->speaker_muted = on;
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
paths = spec->out_paths;
else
paths = spec->speaker_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
spec->autocfg.speaker_pins, on);
spec->autocfg.speaker_pins, paths, on);
/* toggle line-out mutes if needed, too */
/* if LO is a copy of either HP or Speaker, don't need to handle it */
@@ -3815,8 +3861,9 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
on = spec->hp_jack_present;
on |= spec->master_mute;
spec->line_out_muted = on;
paths = spec->out_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
spec->autocfg.line_out_pins, on);
spec->autocfg.line_out_pins, paths, on);
}
EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
@@ -3887,7 +3934,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
/* don't detect pins retasked as outputs */
if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
continue;
if (snd_hda_jack_detect(codec, pin)) {
if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
mux_select(codec, 0, spec->am_entry[i].idx);
return;
}
+1
View File
@@ -220,6 +220,7 @@ struct hda_gen_spec {
unsigned int hp_mic:1; /* Allow HP as a mic-in */
unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */
unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
unsigned int no_multi_io:1; /* Don't try multi I/O config */
unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
unsigned int own_eapd_ctl:1; /* set EAPD by own function */

Some files were not shown because too many files have changed in this diff Show More