Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14864a52 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
  ...
parents 4e13c5d0 75fae117
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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";
+30 −27
Original line number Diff line number Diff line
@@ -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)]
@@ -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;
@@ -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) {
+1 −0
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+32 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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,
Loading