aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 11:26:09 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:28:55 -0500
commit5fe76e4dc60a2c3ff9b1143f5275a953db685e26 (patch)
treef54acdb029f429bf8c0068ed964a1216fbe614d3
parenta4efc230c60ad15584e723755316e67b3c708d67 (diff)
[ALSA] document - Update PM support
Modules: Documentation Update the description about the PCI PM support. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl185
1 files changed, 146 insertions, 39 deletions
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index f2e59fe802bd..4963d83d1511 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
18 </affiliation> 18 </affiliation>
19 </author> 19 </author>
20 20
21 <date>October 6, 2005</date> 21 <date>November 17, 2005</date>
22 <edition>0.3.5</edition> 22 <edition>0.3.6</edition>
23 23
24 <abstract> 24 <abstract>
25 <para> 25 <para>
@@ -2329,9 +2329,14 @@ struct _snd_pcm_runtime {
2329 <constant>PAUSE</constant> bit means that the pcm supports the 2329 <constant>PAUSE</constant> bit means that the pcm supports the
2330 <quote>pause</quote> operation, while the 2330 <quote>pause</quote> operation, while the
2331 <constant>RESUME</constant> bit means that the pcm supports 2331 <constant>RESUME</constant> bit means that the pcm supports
2332 the <quote>suspend/resume</quote> operation. If these flags 2332 the full <quote>suspend/resume</quote> operation.
2333 are set, the <structfield>trigger</structfield> callback below 2333 If <constant>PAUSE</constant> flag is set,
2334 must handle the corresponding commands. 2334 the <structfield>trigger</structfield> callback below
2335 must handle the corresponding (pause push/release) commands.
2336 The suspend/resume trigger commands can be defined even without
2337 <constant>RESUME</constant> flag. See <link
2338 linkend="power-management"><citetitle>
2339 Power Management</citetitle></link> section for details.
2335 </para> 2340 </para>
2336 2341
2337 <para> 2342 <para>
@@ -2903,8 +2908,8 @@ struct _snd_pcm_runtime {
2903 </para> 2908 </para>
2904 2909
2905 <para> 2910 <para>
2906 When the pcm supports the suspend/resume operation 2911 When the pcm supports the suspend/resume operation,
2907 (i.e. <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set), 2912 regardless of full or partial suspend/resume support,
2908 <constant>SUSPEND</constant> and <constant>RESUME</constant> 2913 <constant>SUSPEND</constant> and <constant>RESUME</constant>
2909 commands must be handled, too. 2914 commands must be handled, too.
2910 These commands are issued when the power-management status is 2915 These commands are issued when the power-management status is
@@ -2913,6 +2918,8 @@ struct _snd_pcm_runtime {
2913 do suspend and resume of the pcm substream, and usually, they 2918 do suspend and resume of the pcm substream, and usually, they
2914 are identical with <constant>STOP</constant> and 2919 are identical with <constant>STOP</constant> and
2915 <constant>START</constant> commands, respectively. 2920 <constant>START</constant> commands, respectively.
2921 See <link linkend="power-management"><citetitle>
2922 Power Management</citetitle></link> section for details.
2916 </para> 2923 </para>
2917 2924
2918 <para> 2925 <para>
@@ -5483,22 +5490,60 @@ struct _snd_pcm_runtime {
5483 <constant>CONFIG_PM</constant>. 5490 <constant>CONFIG_PM</constant>.
5484 </para> 5491 </para>
5485 5492
5493 <para>
5494 If the driver supports the suspend/resume
5495 <emphasis>fully</emphasis>, that is, the device can be
5496 properly resumed to the status at the suspend is called,
5497 you can set <constant>SNDRV_PCM_INFO_RESUME</constant> flag
5498 to pcm info field. Usually, this is possible when the
5499 registers of ths chip can be safely saved and restored to the
5500 RAM. If this is set, the trigger callback is called with
5501 <constant>SNDRV_PCM_TRIGGER_RESUME</constant> after resume
5502 callback is finished.
5503 </para>
5504
5505 <para>
5506 Even if the driver doesn't support PM fully but only the
5507 partial suspend/resume is possible, it's still worthy to
5508 implement suspend/resume callbacks. In such a case, applications
5509 would reset the status by calling
5510 <function>snd_pcm_prepare()</function> and restart the stream
5511 appropriately. Hence, you can define suspend/resume callbacks
5512 below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
5513 info flag to the PCM.
5514 </para>
5515
5516 <para>
5517 Note that the trigger with SUSPEND can be always called when
5518 <function>snd_pcm_suspend_all</function> is called,
5519 regardless of <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
5520 The <constant>RESUME</constant> flag affects only the behavior
5521 of <function>snd_pcm_resume()</function>.
5522 (Thus, in theory,
5523 <constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
5524 to be handled in the trigger callback when no
5525 <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set. But,
5526 it's better to keep it for compatibility reason.)
5527 </para>
5486 <para> 5528 <para>
5487 ALSA provides the common power-management layer. Each card driver 5529 In the earlier version of ALSA drivers, a common
5488 needs to have only low-level suspend and resume callbacks. 5530 power-management layer was provided, but it has been removed.
5531 The driver needs to define the suspend/resume hooks according to
5532 the bus the device is assigned. In the case of PCI driver, the
5533 callbacks look like below:
5489 5534
5490 <informalexample> 5535 <informalexample>
5491 <programlisting> 5536 <programlisting>
5492<![CDATA[ 5537<![CDATA[
5493 #ifdef CONFIG_PM 5538 #ifdef CONFIG_PM
5494 static int snd_my_suspend(struct snd_card *card, pm_message_t state) 5539 static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
5495 { 5540 {
5496 .... // do things for suspsend 5541 .... /* do things for suspsend */
5497 return 0; 5542 return 0;
5498 } 5543 }
5499 static int snd_my_resume(struct snd_card *card) 5544 static int snd_my_resume(struct pci_dev *pci)
5500 { 5545 {
5501 .... // do things for suspsend 5546 .... /* do things for suspsend */
5502 return 0; 5547 return 0;
5503 } 5548 }
5504 #endif 5549 #endif
@@ -5511,11 +5556,18 @@ struct _snd_pcm_runtime {
5511 The scheme of the real suspend job is as following. 5556 The scheme of the real suspend job is as following.
5512 5557
5513 <orderedlist> 5558 <orderedlist>
5514 <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem> 5559 <listitem><para>Retrieve the card and the chip data.</para></listitem>
5560 <listitem><para>Call <function>snd_power_change_state()</function> with
5561 <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
5562 power status.</para></listitem>
5515 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem> 5563 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
5564 <listitem><para>If AC97 codecs are used, call
5565 <function>snd_ac97_resume()</function> for each codec.</para></listitem>
5516 <listitem><para>Save the register values if necessary.</para></listitem> 5566 <listitem><para>Save the register values if necessary.</para></listitem>
5517 <listitem><para>Stop the hardware if necessary.</para></listitem> 5567 <listitem><para>Stop the hardware if necessary.</para></listitem>
5518 <listitem><para>Disable the PCI device by calling <function>pci_disable_device()</function>.</para></listitem> 5568 <listitem><para>Disable the PCI device by calling
5569 <function>pci_disable_device()</function>. Then, call
5570 <function>pci_save_state()</function> at last.</para></listitem>
5519 </orderedlist> 5571 </orderedlist>
5520 </para> 5572 </para>
5521 5573
@@ -5525,18 +5577,24 @@ struct _snd_pcm_runtime {
5525 <informalexample> 5577 <informalexample>
5526 <programlisting> 5578 <programlisting>
5527<![CDATA[ 5579<![CDATA[
5528 static int mychip_suspend(struct snd_card *card, pm_message_t state) 5580 static int mychip_suspend(strut pci_dev *pci, pm_message_t state)
5529 { 5581 {
5530 /* (1) */ 5582 /* (1) */
5531 struct mychip *chip = card->pm_private_data; 5583 struct snd_card *card = pci_get_drvdata(pci);
5584 struct mychip *chip = card->private_data;
5532 /* (2) */ 5585 /* (2) */
5533 snd_pcm_suspend_all(chip->pcm); 5586 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
5534 /* (3) */ 5587 /* (3) */
5535 snd_mychip_save_registers(chip); 5588 snd_pcm_suspend_all(chip->pcm);
5536 /* (4) */ 5589 /* (4) */
5537 snd_mychip_stop_hardware(chip); 5590 snd_ac97_suspend(chip->ac97);
5538 /* (5) */ 5591 /* (5) */
5539 pci_disable_device(chip->pci); 5592 snd_mychip_save_registers(chip);
5593 /* (6) */
5594 snd_mychip_stop_hardware(chip);
5595 /* (7) */
5596 pci_disable_device(pci);
5597 pci_save_state(pci);
5540 return 0; 5598 return 0;
5541 } 5599 }
5542]]> 5600]]>
@@ -5548,14 +5606,17 @@ struct _snd_pcm_runtime {
5548 The scheme of the real resume job is as following. 5606 The scheme of the real resume job is as following.
5549 5607
5550 <orderedlist> 5608 <orderedlist>
5551 <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem> 5609 <listitem><para>Retrieve the card and the chip data.</para></listitem>
5552 <listitem><para>Enable the pci device again by calling 5610 <listitem><para>Set up PCI. First, call <function>pci_restore_state()</function>.
5553 <function>pci_enable_device()</function>.</para></listitem> 5611 Then enable the pci device again by calling <function>pci_enable_device()</function>.
5612 Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
5554 <listitem><para>Re-initialize the chip.</para></listitem> 5613 <listitem><para>Re-initialize the chip.</para></listitem>
5555 <listitem><para>Restore the saved registers if necessary.</para></listitem> 5614 <listitem><para>Restore the saved registers if necessary.</para></listitem>
5556 <listitem><para>Resume the mixer, e.g. calling 5615 <listitem><para>Resume the mixer, e.g. calling
5557 <function>snd_ac97_resume()</function>.</para></listitem> 5616 <function>snd_ac97_resume()</function>.</para></listitem>
5558 <listitem><para>Restart the hardware (if any).</para></listitem> 5617 <listitem><para>Restart the hardware (if any).</para></listitem>
5618 <listitem><para>Call <function>snd_power_change_state()</function> with
5619 <constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
5559 </orderedlist> 5620 </orderedlist>
5560 </para> 5621 </para>
5561 5622
@@ -5565,12 +5626,15 @@ struct _snd_pcm_runtime {
5565 <informalexample> 5626 <informalexample>
5566 <programlisting> 5627 <programlisting>
5567<![CDATA[ 5628<![CDATA[
5568 static void mychip_resume(struct mychip *chip) 5629 static int mychip_resume(struct pci_dev *pci)
5569 { 5630 {
5570 /* (1) */ 5631 /* (1) */
5571 struct mychip *chip = card->pm_private_data; 5632 struct snd_card *card = pci_get_drvdata(pci);
5633 struct mychip *chip = card->private_data;
5572 /* (2) */ 5634 /* (2) */
5573 pci_enable_device(chip->pci); 5635 pci_restore_state(pci);
5636 pci_enable_device(pci);
5637 pci_set_master(pci);
5574 /* (3) */ 5638 /* (3) */
5575 snd_mychip_reinit_chip(chip); 5639 snd_mychip_reinit_chip(chip);
5576 /* (4) */ 5640 /* (4) */
@@ -5579,6 +5643,8 @@ struct _snd_pcm_runtime {
5579 snd_ac97_resume(chip->ac97); 5643 snd_ac97_resume(chip->ac97);
5580 /* (6) */ 5644 /* (6) */
5581 snd_mychip_restart_chip(chip); 5645 snd_mychip_restart_chip(chip);
5646 /* (7) */
5647 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
5582 return 0; 5648 return 0;
5583 } 5649 }
5584]]> 5650]]>
@@ -5587,8 +5653,48 @@ struct _snd_pcm_runtime {
5587 </para> 5653 </para>
5588 5654
5589 <para> 5655 <para>
5590 OK, we have all callbacks now. Let's set up them now. In the 5656 As shown in the above, it's better to save registers after
5591 initialization of the card, add the following: 5657 suspending the PCM operations via
5658 <function>snd_pcm_suspend_all()</function> or
5659 <function>snd_pcm_suspend()</function>. It means that the PCM
5660 streams are already stoppped when the register snapshot is
5661 taken. But, remind that you don't have to restart the PCM
5662 stream in the resume callback. It'll be restarted via
5663 trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
5664 when necessary.
5665 </para>
5666
5667 <para>
5668 OK, we have all callbacks now. Let's set them up. In the
5669 initialization of the card, make sure that you can get the chip
5670 data from the card instance, typically via
5671 <structfield>private_data</structfield> field, in case you
5672 created the chip data individually.
5673
5674 <informalexample>
5675 <programlisting>
5676<![CDATA[
5677 static int __devinit snd_mychip_probe(struct pci_dev *pci,
5678 const struct pci_device_id *pci_id)
5679 {
5680 ....
5681 struct snd_card *card;
5682 struct mychip *chip;
5683 ....
5684 card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
5685 ....
5686 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
5687 ....
5688 card->private_data = chip;
5689 ....
5690 }
5691]]>
5692 </programlisting>
5693 </informalexample>
5694
5695 When you created the chip data with
5696 <function>snd_card_new()</function>, it's anyway accessible
5697 via <structfield>private_data</structfield> field.
5592 5698
5593 <informalexample> 5699 <informalexample>
5594 <programlisting> 5700 <programlisting>
@@ -5600,30 +5706,28 @@ struct _snd_pcm_runtime {
5600 struct snd_card *card; 5706 struct snd_card *card;
5601 struct mychip *chip; 5707 struct mychip *chip;
5602 .... 5708 ....
5603 snd_card_set_pm_callback(card, snd_my_suspend, snd_my_resume, chip); 5709 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
5710 sizeof(struct mychip));
5711 ....
5712 chip = card->private_data;
5604 .... 5713 ....
5605 } 5714 }
5606]]> 5715]]>
5607 </programlisting> 5716 </programlisting>
5608 </informalexample> 5717 </informalexample>
5609 5718
5610 Here you don't have to put ifdef CONFIG_PM around, since it's already
5611 checked in the header and expanded to empty if not needed.
5612 </para> 5719 </para>
5613 5720
5614 <para> 5721 <para>
5615 If you need a space for saving the registers, you'll need to 5722 If you need a space for saving the registers, allocate the
5616 allocate the buffer for it here, too, since it would be fatal 5723 buffer for it here, too, since it would be fatal
5617 if you cannot allocate a memory in the suspend phase. 5724 if you cannot allocate a memory in the suspend phase.
5618 The allocated buffer should be released in the corresponding 5725 The allocated buffer should be released in the corresponding
5619 destructor. 5726 destructor.
5620 </para> 5727 </para>
5621 5728
5622 <para> 5729 <para>
5623 And next, set suspend/resume callbacks to the pci_driver, 5730 And next, set suspend/resume callbacks to the pci_driver.
5624 This can be done by passing a macro SND_PCI_PM_CALLBACKS
5625 in the pci_driver struct. This macro is expanded to the correct
5626 (global) callbacks if CONFIG_PM is set.
5627 5731
5628 <informalexample> 5732 <informalexample>
5629 <programlisting> 5733 <programlisting>
@@ -5633,7 +5737,10 @@ struct _snd_pcm_runtime {
5633 .id_table = snd_my_ids, 5737 .id_table = snd_my_ids,
5634 .probe = snd_my_probe, 5738 .probe = snd_my_probe,
5635 .remove = __devexit_p(snd_my_remove), 5739 .remove = __devexit_p(snd_my_remove),
5636 SND_PCI_PM_CALLBACKS 5740 #ifdef CONFIG_PM
5741 .suspend = snd_my_suspend,
5742 .resume = snd_my_resume,
5743 #endif
5637 }; 5744 };
5638]]> 5745]]>
5639 </programlisting> 5746 </programlisting>