mirror of
https://github.com/t2linux/kernel.git
synced 2026-04-30 13:48:59 -07:00
Merge remote-tracking branch 'asoc/fix/fsl' into asoc-linus
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user