Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182714
b: refs/heads/master
c: 47b5d02
h: refs/heads/master
v: v3
  • Loading branch information
Giuliano Pochini authored and Takashi Iwai committed Feb 15, 2010
1 parent d5f8284 commit 6d0a132
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 79 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ad3499f4668f684ef6e5d0222ae14d5e4ade1fdd
refs/heads/master: 47b5d028fdce8f809bf22852ac900338fb90e8aa
153 changes: 138 additions & 15 deletions trunk/sound/pci/echoaudio/echoaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)

spin_lock(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
DE_ACT(("pcm_trigger resume\n"));
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
DE_ACT(("pcm_trigger start\n"));
Expand All @@ -776,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
err = start_transport(chip, channelmask,
chip->pipe_cyclic_mask);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
DE_ACT(("pcm_trigger suspend\n"));
case SNDRV_PCM_TRIGGER_STOP:
DE_ACT(("pcm_trigger stop\n"));
for (i = 0; i < DSP_MAXPIPES; i++) {
Expand Down Expand Up @@ -1951,18 +1955,27 @@ static __devinit int snd_echo_create(struct snd_card *card,
return err;
pci_set_master(pci);

/* allocate a chip-specific data */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
/* Allocate chip if needed */
if (!*rchip) {
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
DE_INIT(("chip=%p\n", chip));
spin_lock_init(&chip->lock);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
atomic_set(&chip->opencount, 0);
mutex_init(&chip->mode_mutex);
chip->can_set_rate = 1;
} else {
/* If this was called from the resume function, chip is
* already allocated and it contains current card settings.
*/
chip = *rchip;
}
DE_INIT(("chip=%p\n", chip));

spin_lock_init(&chip->lock);
chip->card = card;
chip->pci = pci;
chip->irq = -1;

/* PCI resource allocation */
chip->dsp_registers_phys = pci_resource_start(pci, 0);
Expand Down Expand Up @@ -2002,7 +2015,9 @@ static __devinit int snd_echo_create(struct snd_card *card,
chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;

err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
if (err) {
if (err >= 0)
err = set_mixer_defaults(chip);
if (err < 0) {
DE_INIT(("init_hw err=%d\n", err));
snd_echo_free(chip);
return err;
Expand All @@ -2013,9 +2028,6 @@ static __devinit int snd_echo_create(struct snd_card *card,
snd_echo_free(chip);
return err;
}
atomic_set(&chip->opencount, 0);
mutex_init(&chip->mode_mutex);
chip->can_set_rate = 1;
*rchip = chip;
/* Init done ! */
return 0;
Expand Down Expand Up @@ -2048,6 +2060,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,

snd_card_set_dev(card, &pci->dev);

chip = NULL; /* Tells snd_echo_create to allocate chip */
if ((err = snd_echo_create(card, pci, &chip)) < 0) {
snd_card_free(card);
return err;
Expand Down Expand Up @@ -2187,6 +2200,112 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,



#if defined(CONFIG_PM)

static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
{
struct echoaudio *chip = pci_get_drvdata(pci);

DE_INIT(("suspend start\n"));
snd_pcm_suspend_all(chip->analog_pcm);
snd_pcm_suspend_all(chip->digital_pcm);

#ifdef ECHOCARD_HAS_MIDI
/* This call can sleep */
if (chip->midi_out)
snd_echo_midi_output_trigger(chip->midi_out, 0);
#endif
spin_lock_irq(&chip->lock);
if (wait_handshake(chip)) {
spin_unlock_irq(&chip->lock);
return -EIO;
}
clear_handshake(chip);
if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
spin_unlock_irq(&chip->lock);
return -EIO;
}
spin_unlock_irq(&chip->lock);

chip->dsp_code = NULL;
free_irq(chip->irq, chip);
chip->irq = -1;
pci_save_state(pci);
pci_disable_device(pci);

DE_INIT(("suspend done\n"));
return 0;
}



static int snd_echo_resume(struct pci_dev *pci)
{
struct echoaudio *chip = pci_get_drvdata(pci);
struct comm_page *commpage, *commpage_bak;
u32 pipe_alloc_mask;
int err;

DE_INIT(("resume start\n"));
pci_restore_state(pci);
commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
commpage = chip->comm_page;
memcpy(commpage_bak, commpage, sizeof(struct comm_page));

err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
if (err < 0) {
kfree(commpage_bak);
DE_INIT(("resume init_hw err=%d\n", err));
snd_echo_free(chip);
return err;
}
DE_INIT(("resume init OK\n"));

/* Temporarily set chip->pipe_alloc_mask=0 otherwise
* restore_dsp_settings() fails.
*/
pipe_alloc_mask = chip->pipe_alloc_mask;
chip->pipe_alloc_mask = 0;
err = restore_dsp_rettings(chip);
chip->pipe_alloc_mask = pipe_alloc_mask;
if (err < 0) {
kfree(commpage_bak);
return err;
}
DE_INIT(("resume restore OK\n"));

memcpy(&commpage->audio_format, &commpage_bak->audio_format,
sizeof(commpage->audio_format));
memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
sizeof(commpage->sglist_addr));
memcpy(&commpage->midi_output, &commpage_bak->midi_output,
sizeof(commpage->midi_output));
kfree(commpage_bak);

if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
ECHOCARD_NAME, chip)) {
snd_echo_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
}
chip->irq = pci->irq;
DE_INIT(("resume irq=%d\n", chip->irq));

#ifdef ECHOCARD_HAS_MIDI
if (chip->midi_input_enabled)
enable_midi_input(chip, TRUE);
if (chip->midi_out)
snd_echo_midi_output_trigger(chip->midi_out, 1);
#endif

DE_INIT(("resume done\n"));
return 0;
}

#endif /* CONFIG_PM */



static void __devexit snd_echo_remove(struct pci_dev *pci)
{
struct echoaudio *chip;
Expand All @@ -2209,6 +2328,10 @@ static struct pci_driver driver = {
.id_table = snd_echo_ids,
.probe = snd_echo_probe,
.remove = __devexit_p(snd_echo_remove),
#ifdef CONFIG_PM
.suspend = snd_echo_suspend,
.resume = snd_echo_resume,
#endif /* CONFIG_PM */
};


Expand Down
2 changes: 2 additions & 0 deletions trunk/sound/pci/echoaudio/echoaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ static void free_firmware(const struct firmware *fw_entry);

#ifdef ECHOCARD_HAS_MIDI
static int enable_midi_input(struct echoaudio *chip, char enable);
static void snd_echo_midi_output_trigger(
struct snd_rawmidi_substream *substream, int up);
static int midi_service_irq(struct echoaudio *chip);
static int __devinit snd_echo_midi_create(struct snd_card *card,
struct echoaudio *chip);
Expand Down
Loading

0 comments on commit 6d0a132

Please sign in to comment.