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