Skip to content

Commit

Permalink
Merge tag 'sound-fix-3.14-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "The big chunks here are the updates for oxygen driver for Xonar DG
  devices, which were slipped from the previous pull request.  They are
  device-specific and thus not too dangerous.

  Other than that, all patches are small bug fixes, mainly for Samsung
  build fixes, a few HD-audio enhancements, and other misc ASoC fixes.
  (And this time ASoC merge is less than Octopus, lucky seven :)"

* tag 'sound-fix-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (42 commits)
  ALSA: hda/hdmi - allow PIN_OUT to be dynamically enabled
  ALSA: hda - add headset mic detect quirks for another Dell laptop
  ALSA: oxygen: Xonar DG(X): cleanup and minor changes
  ALSA: oxygen: Xonar DG(X): modify high-pass filter control
  ALSA: oxygen: Xonar DG(X): modify input select functions
  ALSA: oxygen: Xonar DG(X): modify capture volume functions
  ALSA: oxygen: Xonar DG(X): use headphone volume control
  ALSA: oxygen: Xonar DG(X): modify playback output select
  ALSA: oxygen: Xonar DG(X): capture from I2S channel 1, not 2
  ALSA: oxygen: Xonar DG(X): move the mixer code into another file
  ALSA: oxygen: modify CS4245 register dumping function
  ALSA: oxygen: modify adjust_dg_dac_routing function
  ALSA: oxygen: Xonar DG(X): modify DAC/ADC parameters function
  ALSA: oxygen: Xonar DG(X): modify initialization functions
  ALSA: oxygen: Xonar DG(X): add new CS4245 SPI functions
  ALSA: oxygen: additional definitions for the Xonar DG/DGX card
  ALSA: oxygen: change description of the xonar_dg.c file
  ALSA: oxygen: export oxygen_update_dac_routing symbol
  ALSA: oxygen: add mute mask for the OXYGEN_PLAY_ROUTING register
  ALSA: oxygen: modify the SPI writing function
  ...
  • Loading branch information
Linus Torvalds committed Jan 31, 2014
2 parents 4e13c5d + 75fae11 commit 14864a5
Show file tree
Hide file tree
Showing 32 changed files with 935 additions and 566 deletions.
2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/sound/simple-card.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Example:
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "left_j";
simple-audio-routing =
simple-audio-card,routing =
"MIC_IN", "Mic Jack",
"Headphone Jack", "HP_OUT",
"Ext Spk", "LINE_OUT";
Expand Down
57 changes: 30 additions & 27 deletions sound/core/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ static inline int init_info_for_card(struct snd_card *card)
#define init_info_for_card(card)
#endif

static int check_empty_slot(struct module *module, int slot)
{
return !slots[slot] || !*slots[slot];
}

/* return an empty slot number (>= 0) found in the given bitmask @mask.
* @mask == -1 == 0xffffffff means: take any free slot up to 32
* when no slot is available, return the original @mask as is.
*/
static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int),
struct module *module)
{
int slot;

for (slot = 0; slot < SNDRV_CARDS; slot++) {
if (slot < 32 && !(mask & (1U << slot)))
continue;
if (!test_bit(slot, snd_cards_lock)) {
if (check(module, slot))
return slot; /* found */
}
}
return mask; /* unchanged */
}

/**
* snd_card_create - create and initialize a soundcard structure
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
Expand All @@ -152,7 +177,7 @@ int snd_card_create(int idx, const char *xid,
struct snd_card **card_ret)
{
struct snd_card *card;
int err, idx2;
int err;

if (snd_BUG_ON(!card_ret))
return -EINVAL;
Expand All @@ -167,32 +192,10 @@ int snd_card_create(int idx, const char *xid,
strlcpy(card->id, xid, sizeof(card->id));
err = 0;
mutex_lock(&snd_card_mutex);
if (idx < 0) {
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
/* idx == -1 == 0xffff means: take any free slot */
if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
continue;
if (!test_bit(idx2, snd_cards_lock)) {
if (module_slot_match(module, idx2)) {
idx = idx2;
break;
}
}
}
}
if (idx < 0) {
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
/* idx == -1 == 0xffff means: take any free slot */
if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
continue;
if (!test_bit(idx2, snd_cards_lock)) {
if (!slots[idx2] || !*slots[idx2]) {
idx = idx2;
break;
}
}
}
}
if (idx < 0) /* first check the matching module-name slot */
idx = get_slot_from_bitmask(idx, module_slot_match, module);
if (idx < 0) /* if not matched, assign an empty slot */
idx = get_slot_from_bitmask(idx, check_empty_slot, module);
if (idx < 0)
err = -ENODEV;
else if (idx < snd_ecards_limit) {
Expand Down
1 change: 1 addition & 0 deletions sound/pci/cs46xx/cs46xx_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ static void free_module_desc(struct dsp_module_desc *module)
kfree(module->segments[i].data);
kfree(module->segments);
}
kfree(module);
}

/* firmware binary format:
Expand Down
1 change: 1 addition & 0 deletions sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ struct hda_codec {
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 */
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
#ifdef CONFIG_PM
unsigned int power_on :1; /* current (global) power-state */
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
Expand Down
34 changes: 32 additions & 2 deletions sound/pci/hda/hda_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <linux/module.h>
#include "hda_codec.h"
#include "hda_local.h"

static int dump_coef = -1;
module_param(dump_coef, int, 0644);
MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)");

static char *bits_names(unsigned int bits, char *names[], int size)
{
int i, n;
Expand Down Expand Up @@ -488,14 +493,39 @@ static void print_unsol_cap(struct snd_info_buffer *buffer,
(unsol & AC_UNSOL_ENABLED) ? 1 : 0);
}

static inline bool can_dump_coef(struct hda_codec *codec)
{
switch (dump_coef) {
case 0: return false;
case 1: return true;
default: return codec->dump_coef;
}
}

static void print_proc_caps(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid)
{
unsigned int i, ncoeff, oldindex;
unsigned int proc_caps = snd_hda_param_read(codec, nid,
AC_PAR_PROC_CAP);
ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT;
snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
proc_caps & AC_PCAP_BENIGN,
(proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT);
proc_caps & AC_PCAP_BENIGN, ncoeff);

if (!can_dump_coef(codec))
return;

/* Note: This is racy - another process could run in parallel and change
the coef index too. */
oldindex = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_COEF_INDEX, 0);
for (i = 0; i < ncoeff; i++) {
unsigned int val;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, i);
val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF,
0);
snd_iprintf(buffer, " Coeff 0x%02x: 0x%04x\n", i, val);
}
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex);
}

static void print_conn_list(struct snd_info_buffer *buffer,
Expand Down
40 changes: 36 additions & 4 deletions sound/pci/hda/patch_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ struct hdmi_spec {

struct hdmi_eld temp_eld;
struct hdmi_ops ops;

bool dyn_pin_out;

/*
* Non-generic VIA/NVIDIA specific
*/
Expand Down Expand Up @@ -500,15 +503,25 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,

static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
{
struct hdmi_spec *spec = codec->spec;
int pin_out;

/* Unmute */
if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
/* Enable pin out: some machines with GM965 gets broken output when
* the pin is disabled or changed while using with HDMI
*/

if (spec->dyn_pin_out)
/* Disable pin out until stream is active */
pin_out = 0;
else
/* Enable pin out: some machines with GM965 gets broken output
* when the pin is disabled or changed while using with HDMI
*/
pin_out = PIN_OUT;

snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out);
}

static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
Expand Down Expand Up @@ -1735,6 +1748,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
hda_nid_t pin_nid = per_pin->pin_nid;
bool non_pcm;
int pinctl;

non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
mutex_lock(&per_pin->lock);
Expand All @@ -1744,6 +1758,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
mutex_unlock(&per_pin->lock);

if (spec->dyn_pin_out) {
pinctl = snd_hda_codec_read(codec, pin_nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl | PIN_OUT);
}

return spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
}

Expand All @@ -1763,6 +1785,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
int cvt_idx, pin_idx;
struct hdmi_spec_per_cvt *per_cvt;
struct hdmi_spec_per_pin *per_pin;
int pinctl;

if (hinfo->nid) {
cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
Expand All @@ -1779,6 +1802,14 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
return -EINVAL;
per_pin = get_pin(spec, pin_idx);

if (spec->dyn_pin_out) {
pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
snd_hda_codec_write(codec, per_pin->pin_nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl & ~PIN_OUT);
}

snd_hda_spdif_ctls_unassign(codec, pin_idx);

mutex_lock(&per_pin->lock);
Expand Down Expand Up @@ -2840,6 +2871,7 @@ static int patch_nvhdmi(struct hda_codec *codec)
return err;

spec = codec->spec;
spec->dyn_pin_out = true;

spec->ops.chmap_cea_alloc_validate_get_type =
nvhdmi_chmap_cea_alloc_validate_get_type;
Expand Down
34 changes: 32 additions & 2 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -1819,6 +1819,7 @@ enum {
ALC889_FIXUP_DAC_ROUTE,
ALC889_FIXUP_MBP_VREF,
ALC889_FIXUP_IMAC91_VREF,
ALC889_FIXUP_MBA11_VREF,
ALC889_FIXUP_MBA21_VREF,
ALC882_FIXUP_INV_DMIC,
ALC882_FIXUP_NO_PRIMARY_HP,
Expand Down Expand Up @@ -1949,6 +1950,16 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
}

/* Set VREF on speaker pins on mba11 */
static void alc889_fixup_mba11_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
static hda_nid_t nids[1] = { 0x18 };

if (action == HDA_FIXUP_ACT_INIT)
alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
}

/* Set VREF on speaker pins on mba21 */
static void alc889_fixup_mba21_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
Expand Down Expand Up @@ -2167,6 +2178,12 @@ static const struct hda_fixup alc882_fixups[] = {
.chained = true,
.chain_id = ALC882_FIXUP_GPIO1,
},
[ALC889_FIXUP_MBA11_VREF] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc889_fixup_mba11_vref,
.chained = true,
.chain_id = ALC889_FIXUP_MBP_VREF,
},
[ALC889_FIXUP_MBA21_VREF] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc889_fixup_mba21_vref,
Expand Down Expand Up @@ -2242,7 +2259,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Expand Down Expand Up @@ -3833,6 +3850,7 @@ enum {
ALC269_FIXUP_ACER_AC700,
ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
ALC269VB_FIXUP_ASUS_ZENBOOK,
ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
ALC269VB_FIXUP_ORDISSIMO_EVE2,
ALC283_FIXUP_CHROME_BOOK,
Expand Down Expand Up @@ -4126,6 +4144,17 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269VB_FIXUP_DMIC,
},
[ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
.type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
/* class-D output amp +5dB */
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
{}
},
.chained = true,
.chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
},
[ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_limit_int_mic_boost,
Expand Down Expand Up @@ -4265,6 +4294,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Expand All @@ -4282,7 +4312,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK),
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Expand Down
2 changes: 1 addition & 1 deletion sound/pci/oxygen/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
snd-oxygen-objs := oxygen.o xonar_dg.o
snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o
snd-virtuoso-objs := virtuoso.o xonar_lib.o \
xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o

Expand Down
7 changes: 5 additions & 2 deletions sound/pci/oxygen/cs4245.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
#define CS4245_ADC_OVFL 0x02
#define CS4245_ADC_UNDRFL 0x01

#define CS4245_SPI_ADDRESS_S (0x9e << 16)
#define CS4245_SPI_WRITE_S (0 << 16)

#define CS4245_SPI_ADDRESS (0x9e << 16)
#define CS4245_SPI_WRITE (0 << 16)
#define CS4245_SPI_ADDRESS 0x9e
#define CS4245_SPI_WRITE 0
#define CS4245_SPI_READ 1
2 changes: 1 addition & 1 deletion sound/pci/oxygen/oxygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
unsigned int index, u16 data, u16 mask);

void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);

void oxygen_reset_uart(struct oxygen *chip);
Expand Down
Loading

0 comments on commit 14864a5

Please sign in to comment.