aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/echoaudio/echoaudio.c
diff options
context:
space:
mode:
authorGiuliano Pochini <pochini@shiny.it>2010-02-14 12:16:10 -0500
committerTakashi Iwai <tiwai@suse.de>2010-02-15 04:40:15 -0500
commit47b5d028fdce8f809bf22852ac900338fb90e8aa (patch)
treea9afb96040863610ca4348d95d120cd430341be0 /sound/pci/echoaudio/echoaudio.c
parentad3499f4668f684ef6e5d0222ae14d5e4ade1fdd (diff)
ALSA: Echoaudio - Add suspend support #2
This patch adds rearranges parts of the initialization code and adds suspend and resume callbacks. This patch adds suspend and resume callbacks. It also rearranges parts of the initialization code so it can be used in both the first initialization (when the module is loaded we also have to load default settings) and the resume callback (where we have to restore the previous settings). Signed-off-by: Giuliano Pochini <pochini@shiny.it> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/echoaudio/echoaudio.c')
-rw-r--r--sound/pci/echoaudio/echoaudio.c153
1 files changed, 138 insertions, 15 deletions
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 79dde9592847..2783ce6c236e 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -753,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
753 753
754 spin_lock(&chip->lock); 754 spin_lock(&chip->lock);
755 switch (cmd) { 755 switch (cmd) {
756 case SNDRV_PCM_TRIGGER_RESUME:
757 DE_ACT(("pcm_trigger resume\n"));
756 case SNDRV_PCM_TRIGGER_START: 758 case SNDRV_PCM_TRIGGER_START:
757 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 759 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
758 DE_ACT(("pcm_trigger start\n")); 760 DE_ACT(("pcm_trigger start\n"));
@@ -776,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
776 err = start_transport(chip, channelmask, 778 err = start_transport(chip, channelmask,
777 chip->pipe_cyclic_mask); 779 chip->pipe_cyclic_mask);
778 break; 780 break;
781 case SNDRV_PCM_TRIGGER_SUSPEND:
782 DE_ACT(("pcm_trigger suspend\n"));
779 case SNDRV_PCM_TRIGGER_STOP: 783 case SNDRV_PCM_TRIGGER_STOP:
780 DE_ACT(("pcm_trigger stop\n")); 784 DE_ACT(("pcm_trigger stop\n"));
781 for (i = 0; i < DSP_MAXPIPES; i++) { 785 for (i = 0; i < DSP_MAXPIPES; i++) {
@@ -1951,18 +1955,27 @@ static __devinit int snd_echo_create(struct snd_card *card,
1951 return err; 1955 return err;
1952 pci_set_master(pci); 1956 pci_set_master(pci);
1953 1957
1954 /* allocate a chip-specific data */ 1958 /* Allocate chip if needed */
1955 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1959 if (!*rchip) {
1956 if (!chip) { 1960 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1957 pci_disable_device(pci); 1961 if (!chip) {
1958 return -ENOMEM; 1962 pci_disable_device(pci);
1963 return -ENOMEM;
1964 }
1965 DE_INIT(("chip=%p\n", chip));
1966 spin_lock_init(&chip->lock);
1967 chip->card = card;
1968 chip->pci = pci;
1969 chip->irq = -1;
1970 atomic_set(&chip->opencount, 0);
1971 mutex_init(&chip->mode_mutex);
1972 chip->can_set_rate = 1;
1973 } else {
1974 /* If this was called from the resume function, chip is
1975 * already allocated and it contains current card settings.
1976 */
1977 chip = *rchip;
1959 } 1978 }
1960 DE_INIT(("chip=%p\n", chip));
1961
1962 spin_lock_init(&chip->lock);
1963 chip->card = card;
1964 chip->pci = pci;
1965 chip->irq = -1;
1966 1979
1967 /* PCI resource allocation */ 1980 /* PCI resource allocation */
1968 chip->dsp_registers_phys = pci_resource_start(pci, 0); 1981 chip->dsp_registers_phys = pci_resource_start(pci, 0);
@@ -2002,7 +2015,9 @@ static __devinit int snd_echo_create(struct snd_card *card,
2002 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; 2015 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
2003 2016
2004 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); 2017 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
2005 if (err) { 2018 if (err >= 0)
2019 err = set_mixer_defaults(chip);
2020 if (err < 0) {
2006 DE_INIT(("init_hw err=%d\n", err)); 2021 DE_INIT(("init_hw err=%d\n", err));
2007 snd_echo_free(chip); 2022 snd_echo_free(chip);
2008 return err; 2023 return err;
@@ -2013,9 +2028,6 @@ static __devinit int snd_echo_create(struct snd_card *card,
2013 snd_echo_free(chip); 2028 snd_echo_free(chip);
2014 return err; 2029 return err;
2015 } 2030 }
2016 atomic_set(&chip->opencount, 0);
2017 mutex_init(&chip->mode_mutex);
2018 chip->can_set_rate = 1;
2019 *rchip = chip; 2031 *rchip = chip;
2020 /* Init done ! */ 2032 /* Init done ! */
2021 return 0; 2033 return 0;
@@ -2048,6 +2060,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2048 2060
2049 snd_card_set_dev(card, &pci->dev); 2061 snd_card_set_dev(card, &pci->dev);
2050 2062
2063 chip = NULL; /* Tells snd_echo_create to allocate chip */
2051 if ((err = snd_echo_create(card, pci, &chip)) < 0) { 2064 if ((err = snd_echo_create(card, pci, &chip)) < 0) {
2052 snd_card_free(card); 2065 snd_card_free(card);
2053 return err; 2066 return err;
@@ -2187,6 +2200,112 @@ ctl_error:
2187 2200
2188 2201
2189 2202
2203#if defined(CONFIG_PM)
2204
2205static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
2206{
2207 struct echoaudio *chip = pci_get_drvdata(pci);
2208
2209 DE_INIT(("suspend start\n"));
2210 snd_pcm_suspend_all(chip->analog_pcm);
2211 snd_pcm_suspend_all(chip->digital_pcm);
2212
2213#ifdef ECHOCARD_HAS_MIDI
2214 /* This call can sleep */
2215 if (chip->midi_out)
2216 snd_echo_midi_output_trigger(chip->midi_out, 0);
2217#endif
2218 spin_lock_irq(&chip->lock);
2219 if (wait_handshake(chip)) {
2220 spin_unlock_irq(&chip->lock);
2221 return -EIO;
2222 }
2223 clear_handshake(chip);
2224 if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
2225 spin_unlock_irq(&chip->lock);
2226 return -EIO;
2227 }
2228 spin_unlock_irq(&chip->lock);
2229
2230 chip->dsp_code = NULL;
2231 free_irq(chip->irq, chip);
2232 chip->irq = -1;
2233 pci_save_state(pci);
2234 pci_disable_device(pci);
2235
2236 DE_INIT(("suspend done\n"));
2237 return 0;
2238}
2239
2240
2241
2242static int snd_echo_resume(struct pci_dev *pci)
2243{
2244 struct echoaudio *chip = pci_get_drvdata(pci);
2245 struct comm_page *commpage, *commpage_bak;
2246 u32 pipe_alloc_mask;
2247 int err;
2248
2249 DE_INIT(("resume start\n"));
2250 pci_restore_state(pci);
2251 commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
2252 commpage = chip->comm_page;
2253 memcpy(commpage_bak, commpage, sizeof(struct comm_page));
2254
2255 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
2256 if (err < 0) {
2257 kfree(commpage_bak);
2258 DE_INIT(("resume init_hw err=%d\n", err));
2259 snd_echo_free(chip);
2260 return err;
2261 }
2262 DE_INIT(("resume init OK\n"));
2263
2264 /* Temporarily set chip->pipe_alloc_mask=0 otherwise
2265 * restore_dsp_settings() fails.
2266 */
2267 pipe_alloc_mask = chip->pipe_alloc_mask;
2268 chip->pipe_alloc_mask = 0;
2269 err = restore_dsp_rettings(chip);
2270 chip->pipe_alloc_mask = pipe_alloc_mask;
2271 if (err < 0) {
2272 kfree(commpage_bak);
2273 return err;
2274 }
2275 DE_INIT(("resume restore OK\n"));
2276
2277 memcpy(&commpage->audio_format, &commpage_bak->audio_format,
2278 sizeof(commpage->audio_format));
2279 memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
2280 sizeof(commpage->sglist_addr));
2281 memcpy(&commpage->midi_output, &commpage_bak->midi_output,
2282 sizeof(commpage->midi_output));
2283 kfree(commpage_bak);
2284
2285 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
2286 ECHOCARD_NAME, chip)) {
2287 snd_echo_free(chip);
2288 snd_printk(KERN_ERR "cannot grab irq\n");
2289 return -EBUSY;
2290 }
2291 chip->irq = pci->irq;
2292 DE_INIT(("resume irq=%d\n", chip->irq));
2293
2294#ifdef ECHOCARD_HAS_MIDI
2295 if (chip->midi_input_enabled)
2296 enable_midi_input(chip, TRUE);
2297 if (chip->midi_out)
2298 snd_echo_midi_output_trigger(chip->midi_out, 1);
2299#endif
2300
2301 DE_INIT(("resume done\n"));
2302 return 0;
2303}
2304
2305#endif /* CONFIG_PM */
2306
2307
2308
2190static void __devexit snd_echo_remove(struct pci_dev *pci) 2309static void __devexit snd_echo_remove(struct pci_dev *pci)
2191{ 2310{
2192 struct echoaudio *chip; 2311 struct echoaudio *chip;
@@ -2209,6 +2328,10 @@ static struct pci_driver driver = {
2209 .id_table = snd_echo_ids, 2328 .id_table = snd_echo_ids,
2210 .probe = snd_echo_probe, 2329 .probe = snd_echo_probe,
2211 .remove = __devexit_p(snd_echo_remove), 2330 .remove = __devexit_p(snd_echo_remove),
2331#ifdef CONFIG_PM
2332 .suspend = snd_echo_suspend,
2333 .resume = snd_echo_resume,
2334#endif /* CONFIG_PM */
2212}; 2335};
2213 2336
2214 2337