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

Commit 3ab345fc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/realtek - Fix lost speaker volume controls
  ALSA: hda/realtek - Create "Bass Speaker" for two speaker pins
  ALSA: hda/realtek - Don't create extra controls with channel suffix
  ALSA: hda - Fix remaining VREF mute-LED NID check in post-3.1 changes
  ALSA: hda - Fix GPIO LED setup for IDT 92HD75 codecs
  ASoC: Provide a more complete DMA driver stub
  ASoC: Remove references to corgi and spitz from machine driver document
  ASoC: Make SND_SOC_MX27VIS_AIC32X4 depend on I2C
  ASoC: Fix dependency for SND_SOC_RAUMFELD and SND_PXA2XX_SOC_HX4700
  ASoC: uda1380: Return proper error in uda1380_modinit failure path
  ASoC: kirkwood: Make SND_KIRKWOOD_SOC_OPENRD and SND_KIRKWOOD_SOC_T5325 depend on I2C
  ASoC: Mark WM8994 ADC muxes as virtual
  ALSA: hda/realtek - Fix Oops in alc_mux_select()
  ALSA: sis7019 - give slow codecs more time to reset
parents 975e32c2 0a34b42b
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -50,8 +50,7 @@ Machine DAI Configuration
The machine DAI configuration glues all the codec and CPU DAIs together. It can
also be used to set up the DAI system clock and for any machine related DAI
initialisation e.g. the machine audio map can be connected to the codec audio
map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c
for examples.
map, unconnected codec pins can be set as such.

struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.

@@ -83,8 +82,7 @@ Machine Power Map
The machine driver can optionally extend the codec power map and to become an
audio power map of the audio subsystem. This allows for automatic power up/down
of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack
sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for
details.
sockets in the machine init function.


Machine Controls
+49 −16
Original line number Diff line number Diff line
@@ -297,6 +297,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
	imux = &spec->input_mux[mux_idx];
	if (!imux->num_items && mux_idx > 0)
		imux = &spec->input_mux[0];
	if (!imux->num_items)
		return 0;

	if (idx >= imux->num_items)
		idx = imux->num_items - 1;
@@ -2629,6 +2631,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
	case AUTO_PIN_SPEAKER_OUT:
		if (cfg->line_outs == 1)
			return "Speaker";
		if (cfg->line_outs == 2)
			return ch ? "Bass Speaker" : "Speaker";
		break;
	case AUTO_PIN_HP_OUT:
		/* for multi-io case, only the primary out */
@@ -2902,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
		if (!nid)
			continue;
		if (found_in_nid_list(nid, spec->multiout.dac_nids,
				      spec->multiout.num_dacs))
				      ARRAY_SIZE(spec->private_dac_nids)))
			continue;
		if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
				      ARRAY_SIZE(spec->multiout.hp_out_nid)))
@@ -2923,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
	return 0;
}

/* return 0 if no possible DAC is found, 1 if one or more found */
static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
				    const hda_nid_t *pins, hda_nid_t *dacs)
{
@@ -2940,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
		if (!dacs[i])
			dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
	}
	return 0;
	return 1;
}

static int alc_auto_fill_multi_ios(struct hda_codec *codec,
@@ -2950,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
static int alc_auto_fill_dac_nids(struct hda_codec *codec)
{
	struct alc_spec *spec = codec->spec;
	const struct auto_pin_cfg *cfg = &spec->autocfg;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	bool redone = false;
	int i;

@@ -2961,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
	spec->multiout.extra_out_nid[0] = 0;
	memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
	spec->multiout.dac_nids = spec->private_dac_nids;
	spec->multi_ios = 0;

	/* fill hard-wired DACs first */
	if (!redone) {
@@ -2994,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
	for (i = 0; i < cfg->line_outs; i++) {
		if (spec->private_dac_nids[i])
			spec->multiout.num_dacs++;
		else
		else {
			memmove(spec->private_dac_nids + i,
				spec->private_dac_nids + i + 1,
				sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
			spec->private_dac_nids[cfg->line_outs - 1] = 0;
		}
	}

	if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
@@ -3019,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
	if (cfg->line_out_type != AUTO_PIN_HP_OUT)
		alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
				 spec->multiout.hp_out_nid);
	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
		alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins,
	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
		int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
					cfg->speaker_pins,
					spec->multiout.extra_out_nid);
		/* if no speaker volume is assigned, try again as the primary
		 * output
		 */
		if (!err && cfg->speaker_outs > 0 &&
		    cfg->line_out_type == AUTO_PIN_HP_OUT) {
			cfg->hp_outs = cfg->line_outs;
			memcpy(cfg->hp_pins, cfg->line_out_pins,
			       sizeof(cfg->hp_pins));
			cfg->line_outs = cfg->speaker_outs;
			memcpy(cfg->line_out_pins, cfg->speaker_pins,
			       sizeof(cfg->speaker_pins));
			cfg->speaker_outs = 0;
			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
			cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
			redone = false;
			goto again;
		}
	}

	return 0;
}
@@ -3171,7 +3198,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
}

static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
				     hda_nid_t dac, const char *pfx)
				     hda_nid_t dac, const char *pfx,
				     int cidx)
{
	struct alc_spec *spec = codec->spec;
	hda_nid_t sw, vol;
@@ -3187,15 +3215,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
		if (is_ctl_used(spec->sw_ctls, val))
			return 0; /* already created */
		mark_ctl_usage(spec->sw_ctls, val);
		return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
		return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
	}

	sw = alc_look_for_out_mute_nid(codec, pin, dac);
	vol = alc_look_for_out_vol_nid(codec, pin, dac);
	err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
	err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol);
	if (err < 0)
		return err;
	err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
	err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw);
	if (err < 0)
		return err;
	return 0;
@@ -3236,16 +3264,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
		hda_nid_t dac = *dacs;
		if (!dac)
			dac = spec->multiout.dac_nids[0];
		return alc_auto_create_extra_out(codec, *pins, dac, pfx);
		return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
	}

	if (dacs[num_pins - 1]) {
		/* OK, we have a multi-output system with individual volumes */
		for (i = 0; i < num_pins; i++) {
			if (num_pins >= 3) {
				snprintf(name, sizeof(name), "%s %s",
					 pfx, channel_name[i]);
				err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
							name);
								name, 0);
			} else {
				err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
								pfx, i);
			}
			if (err < 0)
				return err;
		}
+25 −22
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ struct sigmatel_spec {
	unsigned int gpio_mute;
	unsigned int gpio_led;
	unsigned int gpio_led_polarity;
	unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
	unsigned int vref_led;

	/* stream */
@@ -4318,14 +4319,12 @@ static void stac_store_hints(struct hda_codec *codec)
		spec->eapd_switch = val;
	get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
	if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
		if (spec->gpio_led <= 8) {
		spec->gpio_mask |= spec->gpio_led;
		spec->gpio_dir |= spec->gpio_led;
		if (spec->gpio_led_polarity)
			spec->gpio_data |= spec->gpio_led;
	}
}
}

static int stac92xx_init(struct hda_codec *codec)
{
@@ -4443,7 +4442,7 @@ static int stac92xx_init(struct hda_codec *codec)
		/* power on when no jack detection is available */
		/* or when the VREF is used for controlling LED */
		if (!spec->hp_detect ||
		    (spec->gpio_led > 8 && spec->gpio_led == nid)) {
		    spec->vref_mute_led_nid == nid) {
			stac_toggle_power_map(codec, nid, 1);
			continue;
		}
@@ -4915,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
			if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
				  &spec->gpio_led_polarity,
				  &spec->gpio_led) == 2) {
				if (spec->gpio_led < 4)
				unsigned int max_gpio;
				max_gpio = snd_hda_param_read(codec, codec->afg,
							      AC_PAR_GPIO_CAP);
				max_gpio &= AC_GPIO_IO_COUNT;
				if (spec->gpio_led < max_gpio)
					spec->gpio_led = 1 << spec->gpio_led;
				else
					spec->vref_mute_led_nid = spec->gpio_led;
				return 1;
			}
			if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5045,15 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
	struct sigmatel_spec *spec = codec->spec;

	/* sync mute LED */
	if (spec->gpio_led) {
		if (spec->gpio_led <= 8) {
	if (spec->vref_mute_led_nid)
		stac_vrefout_set(codec, spec->vref_mute_led_nid,
				 spec->vref_led);
	else if (spec->gpio_led)
		stac_gpio_set(codec, spec->gpio_mask,
			      spec->gpio_dir, spec->gpio_data);
		} else {
			stac_vrefout_set(codec,
					spec->gpio_led, spec->vref_led);
		}
	}
	return 0;
}

@@ -5064,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
	struct sigmatel_spec *spec = codec->spec;

	if (power_state == AC_PWRST_D3) {
		if (spec->gpio_led > 8) {
		if (spec->vref_mute_led_nid) {
			/* with vref-out pin used for mute led control
			 * codec AFG is prevented from D3 state
			 */
@@ -5117,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
		}
	}
	/*polarity defines *not* muted state level*/
	if (spec->gpio_led <= 8) {
	if (!spec->vref_mute_led_nid) {
		if (muted)
			spec->gpio_data &= ~spec->gpio_led; /* orange */
		else
@@ -5135,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
		muted_lvl = spec->gpio_led_polarity ?
				AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
		spec->vref_led = muted ? muted_lvl : notmtd_lvl;
		stac_vrefout_set(codec,	spec->gpio_led, spec->vref_led);
		stac_vrefout_set(codec,	spec->vref_mute_led_nid,
				 spec->vref_led);
	}
	return 0;
}
@@ -5649,7 +5652,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)

#ifdef CONFIG_SND_HDA_POWER_SAVE
	if (spec->gpio_led) {
		if (spec->gpio_led <= 8) {
		if (!spec->vref_mute_led_nid) {
			spec->gpio_mask |= spec->gpio_led;
			spec->gpio_dir |= spec->gpio_led;
			spec->gpio_data |= spec->gpio_led;
@@ -5962,7 +5965,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)

#ifdef CONFIG_SND_HDA_POWER_SAVE
	if (spec->gpio_led) {
		if (spec->gpio_led <= 8) {
		if (!spec->vref_mute_led_nid) {
			spec->gpio_mask |= spec->gpio_led;
			spec->gpio_dir |= spec->gpio_led;
			spec->gpio_data |= spec->gpio_led;
+53 −11
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
static int enable = 1;
static int codecs = 1;

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
@@ -48,6 +49,8 @@ module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
module_param(codecs, int, 0444);
MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");

static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
@@ -140,6 +143,9 @@ struct sis7019 {
	dma_addr_t silence_dma_addr;
};

/* These values are also used by the module param 'codecs' to indicate
 * which codecs should be present.
 */
#define SIS_PRIMARY_CODEC_PRESENT	0x0001
#define SIS_SECONDARY_CODEC_PRESENT	0x0002
#define SIS_TERTIARY_CODEC_PRESENT	0x0004
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis)
{
	unsigned long io = sis->ioport;
	void __iomem *ioaddr = sis->ioaddr;
	unsigned long timeout;
	u16 status;
	int count;
	int i;
@@ -1104,8 +1111,20 @@ static int sis_chip_init(struct sis7019 *sis)
	while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
		udelay(1);

	/* Command complete, we can let go of the semaphore now.
	 */
	outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
	if (!count)
		return -EIO;

	/* Now that we've finished the reset, find out what's attached.
	 * There are some codec/board combinations that take an extremely
	 * long time to come up. 350+ ms has been observed in the field,
	 * so we'll give them up to 500ms.
	 */
	sis->codecs_present = 0;
	timeout = msecs_to_jiffies(500) + jiffies;
	while (time_before_eq(jiffies, timeout)) {
		status = inl(io + SIS_AC97_STATUS);
		if (status & SIS_AC97_STATUS_CODEC_READY)
			sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
@@ -1114,11 +1133,23 @@ static int sis_chip_init(struct sis7019 *sis)
		if (status & SIS_AC97_STATUS_CODEC3_READY)
			sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;

	/* All done, let go of the semaphore, and check for errors
		if (sis->codecs_present == codecs)
			break;

		msleep(1);
	}

	/* All done, check for errors.
	 */
	outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
	if (!sis->codecs_present || !count)
	if (!sis->codecs_present) {
		printk(KERN_ERR "sis7019: could not find any codecs\n");
		return -EIO;
	}

	if (sis->codecs_present != codecs) {
		printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n",
		       sis->codecs_present, codecs);
	}

	/* Let the hardware know that the audio driver is alive,
	 * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci,
	if (!enable)
		goto error_out;

	/* The user can specify which codecs should be present so that we
	 * can wait for them to show up if they are slow to recover from
	 * the AC97 cold reset. We default to a single codec, the primary.
	 *
	 * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
	 */
	codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
		  SIS_TERTIARY_CODEC_PRESENT;
	if (!codecs)
		codecs = SIS_PRIMARY_CODEC_PRESENT;

	rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card);
	if (rc < 0)
		goto error_out;
+2 −2
Original line number Diff line number Diff line
@@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = {

static int __init uda1380_modinit(void)
{
	int ret;
	int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
	ret = i2c_add_driver(&uda1380_i2c_driver);
	if (ret != 0)
		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
#endif
	return 0;
	return ret;
}
module_init(uda1380_modinit);

Loading