Skip to content

Commit

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

Pull sound fixes from Takashi Iwai:
 "This batch contains a few USB audio fixes, a couple of HD-audio
  quirks, various small ASoC driver fixes in addition to an ASoC core
  fix that may lead to memory corruption.

  Unfortunately slightly more volume than the previous pull request, but
  all are reasonable regression fixes"

* tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Add a fixup for Gateway LT27
  ASoC: tegra: fix Tegra30 I2S capture parameter setup
  ALSA: usb-audio: Fix invalid volume resolution for Logitech HD Webcam C525
  ALSA: hda - Fix missing mute controls for CX5051
  ALSA: usb-audio: fix automatic Roland/Yamaha MIDI detection
  ALSA: 6fire: make buffers DMA-able (midi)
  ALSA: 6fire: make buffers DMA-able (pcm)
  ALSA: hda - Add pinfix for LG LW25 laptop
  ASoC: cs42l52: Add new TLV for Beep Volume
  ASoC: cs42l52: Reorder Min/Max and update to SX_TLV for Beep Volume
  ASoC: dapm: Fix empty list check in dapm_new_mux()
  ASoC: sgtl5000: fix buggy 'Capture Attenuate Switch' control
  ASoC: sgtl5000: prevent playback to be muted when terminating concurrent capture
  • Loading branch information
Linus Torvalds committed Aug 16, 2013
2 parents 89cb9ae + 1801928 commit f43c606
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 23 deletions.
6 changes: 3 additions & 3 deletions sound/pci/hda/hda_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1,
}

#define nid_has_mute(codec, nid, dir) \
check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
#define nid_has_volume(codec, nid, dir) \
check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)

Expand Down Expand Up @@ -624,7 +624,7 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
if (enable)
val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
}
if (caps & AC_AMPCAP_MUTE) {
if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) {
if (!enable)
val |= HDA_AMP_MUTE;
}
Expand All @@ -648,7 +648,7 @@ static unsigned int get_amp_mask_to_modify(struct hda_codec *codec,
{
unsigned int mask = 0xff;

if (caps & AC_AMPCAP_MUTE) {
if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) {
if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_MUTE_CTL))
mask &= ~0x80;
}
Expand Down
11 changes: 11 additions & 0 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ enum {
ALC880_FIXUP_GPIO2,
ALC880_FIXUP_MEDION_RIM,
ALC880_FIXUP_LG,
ALC880_FIXUP_LG_LW25,
ALC880_FIXUP_W810,
ALC880_FIXUP_EAPD_COEF,
ALC880_FIXUP_TCL_S700,
Expand Down Expand Up @@ -1089,6 +1090,14 @@ static const struct hda_fixup alc880_fixups[] = {
{ }
}
},
[ALC880_FIXUP_LG_LW25] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x1a, 0x0181344f }, /* line-in */
{ 0x1b, 0x0321403f }, /* headphone */
{ }
}
},
[ALC880_FIXUP_W810] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
Expand Down Expand Up @@ -1341,6 +1350,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = {
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),

/* Below is the copied entries from alc880_quirks.c.
Expand Down Expand Up @@ -4329,6 +4339,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Expand Down
5 changes: 4 additions & 1 deletion sound/soc/codecs/cs42l52.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);

static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0);

static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0);

static const unsigned int limiter_tlv[] = {
TLV_DB_RANGE_HEAD(2),
0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
Expand Down Expand Up @@ -451,7 +453,8 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
SOC_ENUM("Beep Pitch", beep_pitch_enum),
SOC_ENUM("Beep on Time", beep_ontime_enum),
SOC_ENUM("Beep off Time", beep_offtime_enum),
SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv),
SOC_SINGLE_SX_TLV("Beep Volume", CS42L52_BEEP_VOL,
0, 0x07, 0x1f, beep_tlv),
SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1),
SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
Expand Down
18 changes: 14 additions & 4 deletions sound/soc/codecs/sgtl5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,26 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
static int power_vag_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP;

switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
break;

case SND_SOC_DAPM_PRE_PMD:
snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, 0);
msleep(400);
/*
* Don't clear VAG_POWERUP, when both DAC and ADC are
* operational to prevent inadvertently starving the
* other one of them.
*/
if ((snd_soc_read(w->codec, SGTL5000_CHIP_ANA_POWER) &
mask) != mask) {
snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, 0);
msleep(400);
}
break;
default:
break;
Expand Down Expand Up @@ -388,7 +398,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
SGTL5000_CHIP_ANA_ADC_CTRL,
8, 2, 0, capture_6db_attenuate),
8, 1, 0, capture_6db_attenuate),
SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),

SOC_DOUBLE_TLV("Headphone Playback Volume",
Expand Down
7 changes: 4 additions & 3 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,13 +679,14 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
return -EINVAL;
}

path = list_first_entry(&w->sources, struct snd_soc_dapm_path,
list_sink);
if (!path) {
if (list_empty(&w->sources)) {
dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name);
return -EINVAL;
}

path = list_first_entry(&w->sources, struct snd_soc_dapm_path,
list_sink);

ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path);
if (ret < 0)
return ret;
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/tegra/tegra30_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
reg = TEGRA30_I2S_CIF_RX_CTRL;
} else {
val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
reg = TEGRA30_I2S_CIF_RX_CTRL;
reg = TEGRA30_I2S_CIF_TX_CTRL;
}

regmap_write(i2s->regmap, reg, val);
Expand Down
16 changes: 15 additions & 1 deletion sound/usb/6fire/midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "chip.h"
#include "comm.h"

enum {
MIDI_BUFSIZE = 64
};

static void usb6fire_midi_out_handler(struct urb *urb)
{
struct midi_runtime *rt = urb->context;
Expand Down Expand Up @@ -156,6 +160,12 @@ int usb6fire_midi_init(struct sfire_chip *chip)
if (!rt)
return -ENOMEM;

rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL);
if (!rt->out_buffer) {
kfree(rt);
return -ENOMEM;
}

rt->chip = chip;
rt->in_received = usb6fire_midi_in_received;
rt->out_buffer[0] = 0x80; /* 'send midi' command */
Expand All @@ -169,6 +179,7 @@ int usb6fire_midi_init(struct sfire_chip *chip)

ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
if (ret < 0) {
kfree(rt->out_buffer);
kfree(rt);
snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
return ret;
Expand Down Expand Up @@ -197,6 +208,9 @@ void usb6fire_midi_abort(struct sfire_chip *chip)

void usb6fire_midi_destroy(struct sfire_chip *chip)
{
kfree(chip->midi);
struct midi_runtime *rt = chip->midi;

kfree(rt->out_buffer);
kfree(rt);
chip->midi = NULL;
}
6 changes: 1 addition & 5 deletions sound/usb/6fire/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

#include "common.h"

enum {
MIDI_BUFSIZE = 64
};

struct midi_runtime {
struct sfire_chip *chip;
struct snd_rawmidi *instance;
Expand All @@ -32,7 +28,7 @@ struct midi_runtime {
struct snd_rawmidi_substream *out;
struct urb out_urb;
u8 out_serial; /* serial number of out packet */
u8 out_buffer[MIDI_BUFSIZE];
u8 *out_buffer;
int buffer_offset;

void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
Expand Down
41 changes: 40 additions & 1 deletion sound/usb/6fire/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
}

static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
{
int i;

for (i = 0; i < PCM_N_URBS; i++) {
rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
if (!rt->out_urbs[i].buffer)
return -ENOMEM;
rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
if (!rt->in_urbs[i].buffer)
return -ENOMEM;
}
return 0;
}

static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
{
int i;

for (i = 0; i < PCM_N_URBS; i++) {
kfree(rt->out_urbs[i].buffer);
kfree(rt->in_urbs[i].buffer);
}
}

int usb6fire_pcm_init(struct sfire_chip *chip)
{
int i;
Expand All @@ -593,6 +620,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
if (!rt)
return -ENOMEM;

ret = usb6fire_pcm_buffers_init(rt);
if (ret) {
usb6fire_pcm_buffers_destroy(rt);
kfree(rt);
return ret;
}

rt->chip = chip;
rt->stream_state = STREAM_DISABLED;
rt->rate = ARRAY_SIZE(rates);
Expand All @@ -614,6 +648,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip)

ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
if (ret < 0) {
usb6fire_pcm_buffers_destroy(rt);
kfree(rt);
snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
return ret;
Expand All @@ -625,6 +660,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);

if (ret) {
usb6fire_pcm_buffers_destroy(rt);
kfree(rt);
snd_printk(KERN_ERR PREFIX
"error preallocating pcm buffers.\n");
Expand Down Expand Up @@ -669,6 +705,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)

void usb6fire_pcm_destroy(struct sfire_chip *chip)
{
kfree(chip->pcm);
struct pcm_runtime *rt = chip->pcm;

usb6fire_pcm_buffers_destroy(rt);
kfree(rt);
chip->pcm = NULL;
}
2 changes: 1 addition & 1 deletion sound/usb/6fire/pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct pcm_urb {
struct urb instance;
struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
/* END DO NOT SEPARATE */
u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
u8 *buffer;

struct pcm_urb *peer;
};
Expand Down
1 change: 1 addition & 0 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
case USB_ID(0x046d, 0x0991):
/* Most audio usb devices lie about volume resolution.
* Most Logitech webcams have res = 384.
Expand Down
6 changes: 3 additions & 3 deletions sound/usb/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,19 @@ static int create_auto_midi_quirk(struct snd_usb_audio *chip,
if (altsd->bNumEndpoints < 1)
return -ENODEV;
epd = get_endpoint(alts, 0);
if (!usb_endpoint_xfer_bulk(epd) ||
if (!usb_endpoint_xfer_bulk(epd) &&
!usb_endpoint_xfer_int(epd))
return -ENODEV;

switch (USB_ID_VENDOR(chip->usb_id)) {
case 0x0499: /* Yamaha */
err = create_yamaha_midi_quirk(chip, iface, driver, alts);
if (err < 0 && err != -ENODEV)
if (err != -ENODEV)
return err;
break;
case 0x0582: /* Roland */
err = create_roland_midi_quirk(chip, iface, driver, alts);
if (err < 0 && err != -ENODEV)
if (err != -ENODEV)
return err;
break;
}
Expand Down

0 comments on commit f43c606

Please sign in to comment.