提交 f470b8c2 编写于 作者: L Linus Torvalds

Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "The highlight of this update is the fixes for ASoC kirkwood by
  Russell.  In addition to that, a couple of regression fixes for
  HD-audio due to the runtime PM support on 3.7, and other driver-
  specific regression fixes like USB MIDI on non-standard USB audio
  drivers."

* tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: snd-usb: properly initialize the sync endpoint
  ALSA: hda - Cirrus: Correctly clear line_out_pins when moving to speaker
  ALSA: hda - Add support for Realtek ALC292
  ASoC: kirkwood-i2s: more pause-mode fixes
  ASoC: kirkwood-i2s: fix DMA underruns
  ASoC: kirkwood-i2s: fix DCO lock detection
  ASoC: kirkwood-dma: don't ignore other irq causes on error
  ASoC: kirkwood-dma: fix use of virt_to_phys()
  ALSA: hda - Limit runtime PM support only to known Intel chips
  ALSA: hda - Fix recursive suspend/resume call
  ALSA: ua101, usx2y: fix broken MIDI output
  ASoC: arizona: Fix typo - Swap value in 48k_rates[] and 44k1_rates[]
  ASoC: bells: Fix up git patch application failure
  ASoC: cs4271: free allocated GPIO
......@@ -228,7 +228,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
}
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
if (res && *res == -1 && bus->rirb_error) {
if (!codec->in_pm && res && *res == -1 && bus->rirb_error) {
if (bus->response_reset) {
snd_printd("hda_codec: resetting BUS due to "
"fatal communication error\n");
......@@ -238,7 +238,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
goto again;
}
/* clear reset-flag when the communication gets recovered */
if (!err)
if (!err || codec->in_pm)
bus->response_reset = 0;
return err;
}
......@@ -3616,6 +3616,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
{
unsigned int state;
codec->in_pm = 1;
if (codec->patch_ops.suspend)
codec->patch_ops.suspend(codec);
hda_cleanup_all_streams(codec);
......@@ -3630,6 +3632,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
codec->power_transition = 0;
codec->power_jiffies = jiffies;
spin_unlock(&codec->power_lock);
codec->in_pm = 0;
return state;
}
......@@ -3638,6 +3641,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
*/
static void hda_call_codec_resume(struct hda_codec *codec)
{
codec->in_pm = 1;
/* set as if powered on for avoiding re-entering the resume
* in the resume / power-save sequence
*/
......@@ -3656,6 +3661,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
snd_hda_codec_resume_cache(codec);
}
snd_hda_jack_report_sync(codec);
codec->in_pm = 0;
snd_hda_power_down(codec); /* flag down before returning */
}
#endif /* CONFIG_PM */
......
......@@ -869,6 +869,7 @@ struct hda_codec {
unsigned int power_on :1; /* current (global) power-state */
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
unsigned int pm_down_notified:1; /* PM notified to controller */
unsigned int in_pm:1; /* suspend/resume being performed */
int power_transition; /* power-state in transition */
int power_count; /* current (global) power refcount */
struct delayed_work power_work; /* delayed task for powerdown */
......
......@@ -556,6 +556,12 @@ enum {
#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
/* quirks for Intel PCH */
#define AZX_DCAPS_INTEL_PCH \
(AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME)
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
......@@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up)
{
struct azx *chip = bus->private_data;
if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
return;
if (power_up)
pm_runtime_get_sync(&chip->pci->dev);
else
......@@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev)
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip = card->private_data;
if (!power_save_controller)
if (!power_save_controller ||
!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
return -EAGAIN;
azx_stop_chip(chip);
......@@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci)
static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* CPT */
{ PCI_DEVICE(0x8086, 0x1c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* PBG */
{ PCI_DEVICE(0x8086, 0x1d20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE},
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Panther Point */
{ PCI_DEVICE(0x8086, 0x1e20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point */
{ PCI_DEVICE(0x8086, 0x8c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c21),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
/* Haswell */
{ PCI_DEVICE(0x8086, 0x0c0c),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
{ PCI_DEVICE(0x8086, 0x0d0c),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
/* 5 Series/3400 */
{ PCI_DEVICE(0x8086, 0x3b56),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
......
......@@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec)
memcpy(cfg->speaker_pins, cfg->line_out_pins,
sizeof(cfg->speaker_pins));
cfg->line_outs = 0;
memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins));
}
return 0;
......
......@@ -7065,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
{ .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
.patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
......
......@@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev);
static unsigned int arizona_sysclk_48k_rates[] = {
6144000,
12288000,
22579200,
24576000,
49152000,
73728000,
98304000,
......@@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = {
static unsigned int arizona_sysclk_44k1_rates[] = {
5644800,
11289600,
24576000,
22579200,
45158400,
67737600,
90316800,
......
......@@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
gpio_nreset = cs4271plat->gpio_nreset;
if (gpio_nreset >= 0)
if (gpio_request(gpio_nreset, "CS4271 Reset"))
if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
gpio_nreset = -EINVAL;
if (gpio_nreset >= 0) {
/* Reset codec */
......@@ -535,15 +535,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
static int cs4271_remove(struct snd_soc_codec *codec)
{
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
int gpio_nreset;
gpio_nreset = cs4271->gpio_nreset;
if (gpio_is_valid(gpio_nreset)) {
if (gpio_is_valid(cs4271->gpio_nreset))
/* Set codec to the reset state */
gpio_set_value(gpio_nreset, 0);
gpio_free(gpio_nreset);
}
gpio_set_value(cs4271->gpio_nreset, 0);
return 0;
};
......
......@@ -71,7 +71,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
printk(KERN_WARNING "%s: got err interrupt 0x%lx\n",
__func__, cause);
writel(cause, priv->io + KIRKWOOD_ERR_CAUSE);
return IRQ_HANDLED;
}
/* we've enabled only bytes interrupts ... */
......@@ -178,7 +177,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
}
dram = mv_mbus_dram_info();
addr = virt_to_phys(substream->dma_buffer.area);
addr = substream->dma_buffer.addr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
prdata->play_stream = substream;
kirkwood_dma_conf_mbus_windows(priv->io,
......
......@@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
do {
cpu_relax();
value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
value &= KIRKWOOD_DCO_SPCR_STATUS;
value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK;
} while (value == 0);
}
......@@ -180,67 +180,72 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
unsigned long value;
/*
* specs says KIRKWOOD_PLAYCTL must be read 2 times before
* changing it. So read 1 time here and 1 later.
*/
value = readl(priv->io + KIRKWOOD_PLAYCTL);
uint32_t ctl, value;
ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
unsigned timeout = 5000;
/*
* The Armada510 spec says that if we enter pause mode, the
* busy bit must be read back as clear _twice_. Make sure
* we respect that otherwise we get DMA underruns.
*/
do {
value = ctl;
ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
break;
udelay(1);
} while (timeout--);
if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
ctl);
}
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* stop audio, enable interrupts */
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value |= KIRKWOOD_PLAYCTL_PAUSE;
writel(value, priv->io + KIRKWOOD_PLAYCTL);
value = readl(priv->io + KIRKWOOD_INT_MASK);
value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
/* configure audio & enable i2s playback */
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
| KIRKWOOD_PLAYCTL_SPDIF_EN);
if (priv->burst == 32)
value |= KIRKWOOD_PLAYCTL_BURST_32;
ctl |= KIRKWOOD_PLAYCTL_BURST_32;
else
value |= KIRKWOOD_PLAYCTL_BURST_128;
value |= KIRKWOOD_PLAYCTL_I2S_EN;
writel(value, priv->io + KIRKWOOD_PLAYCTL);
ctl |= KIRKWOOD_PLAYCTL_BURST_128;
ctl |= KIRKWOOD_PLAYCTL_I2S_EN;
writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_STOP:
/* stop audio, disable interrupts */
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
writel(value, priv->io + KIRKWOOD_PLAYCTL);
ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
value = readl(priv->io + KIRKWOOD_INT_MASK);
value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
/* disable all playbacks */
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
writel(value, priv->io + KIRKWOOD_PLAYCTL);
ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
writel(value, priv->io + KIRKWOOD_PLAYCTL);
ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
value = readl(priv->io + KIRKWOOD_PLAYCTL);
value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
writel(value, priv->io + KIRKWOOD_PLAYCTL);
ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
break;
default:
......@@ -260,11 +265,6 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* stop audio, enable interrupts */
value = readl(priv->io + KIRKWOOD_RECCTL);
value |= KIRKWOOD_RECCTL_PAUSE;
writel(value, priv->io + KIRKWOOD_RECCTL);
value = readl(priv->io + KIRKWOOD_INT_MASK);
value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
writel(value, priv->io + KIRKWOOD_INT_MASK);
......
......@@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = {
{
.name = "Sub",
.stream_name = "Sub",
.cpu_dai_name = "wm5110-aif3",
.cpu_dai_name = "wm5102-aif3",
.codec_dai_name = "wm9081-hifi",
.codec_name = "wm9081.1-006c",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
......@@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = {
{
.name = "Sub",
.stream_name = "Sub",
.cpu_dai_name = "wm5102-aif3",
.cpu_dai_name = "wm5110-aif3",
.codec_dai_name = "wm9081-hifi",
.codec_name = "wm9081.1-006c",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
......
......@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint {
struct snd_usb_midi_out_endpoint* ep;
struct snd_rawmidi_substream *substream;
int active;
bool autopm_reference;
uint8_t cable; /* cable number << 4 */
uint8_t state;
#define STATE_UNKNOWN 0
......@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
return -ENXIO;
}
err = usb_autopm_get_interface(umidi->iface);
if (err < 0)
port->autopm_reference = err >= 0;
if (err < 0 && err != -EACCES)
return -EIO;
substream->runtime->private_data = port;
port->state = STATE_UNKNOWN;
......@@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_usb_midi* umidi = substream->rmidi->private_data;
struct usbmidi_out_port *port = substream->runtime->private_data;
substream_open(substream, 0);
usb_autopm_put_interface(umidi->iface);
if (port->autopm_reference)
usb_autopm_put_interface(umidi->iface);
return 0;
}
......
......@@ -459,7 +459,7 @@ static int configure_endpoint(struct snd_usb_substream *subs)
return ret;
if (subs->sync_endpoint)
ret = snd_usb_endpoint_set_params(subs->data_endpoint,
ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
subs->pcm_format,
subs->channels,
subs->period_bytes,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册