fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / Documentation / sound / alsa / DocBook / writing-an-alsa-driver.tmpl
index 82d4029..ccd0a95 100644 (file)
@@ -18,8 +18,8 @@
       </affiliation>
      </author>
 
-     <date>July 11, 2004</date>
-     <edition>0.3.3</edition>
+     <date>November 17, 2005</date>
+     <edition>0.3.6</edition>
 
     <abstract>
       <para>
@@ -30,7 +30,7 @@
 
     <legalnotice>
     <para>
-    Copyright (c) 2002-2004  Takashi Iwai <email>tiwai@suse.de</email>
+    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
     </para>
 
     <para>
       </para>
 
       <para>
-        One is the the trees provided as a tarball or via cvs from the
+        One is the trees provided as a tarball or via cvs from the
       ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
-      tree. To synchronize both, the ALSA driver tree is split to
+      tree. To synchronize both, the ALSA driver tree is split into
       two different trees: alsa-kernel and alsa-driver. The former
       contains purely the source codes for the Linux 2.6 (or later)
       tree. This tree is designed only for compilation on 2.6 or
           <listitem><para>create <function>probe()</function> callback.</para></listitem>
           <listitem><para>create <function>remove()</function> callback.</para></listitem>
           <listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
-          <listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem>
+          <listitem><para>create <function>init()</function> function just calling <function>pci_register_driver()</function> to register the pci_driver table defined above.</para></listitem>
           <listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
         </itemizedlist>
       </para>
   static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
   /* definition of the chip-specific record */
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           // rest of implementation will be in the section
           // "PCI Resource Managements"
   };
   /* chip-specific destructor
    * (see "PCI Resource Managements")
    */
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           .... // will be implemented later...
   }
   /* component-destructor
    * (see "Management of Cards and Components")
    */
-  static int snd_mychip_dev_free(snd_device_t *device)
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = device->device_data;
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 
   /* chip-specific constructor
    * (see "Management of Cards and Components")
    */
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
           ....
 
           /* allocate a chip-specific data with zero filled */
-          chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           if (chip == NULL)
                   return -ENOMEM;
 
                                const struct pci_device_id *pci_id)
   {
           static int dev;
-          snd_card_t *card;
-          mychip_t *chip;
+          struct snd_card *card;
+          struct mychip *chip;
           int err;
 
           /* (1) */
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   ....
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 ]]>
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip;
+  struct mychip *chip;
   ....
   if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
           snd_card_free(card);
       </para>
 
       <para>
-      The ALSA interfaces like PCM or control API are define in other
+      The ALSA interfaces like PCM or control API are defined in other
       header files as <filename>&lt;sound/xxx.h&gt;</filename>.
       They have to be included after
       <filename>&lt;sound/core.h&gt;</filename>.
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   card = snd_card_new(index, id, module, extra_size);
 ]]>
           </programlisting>
       <para>
         After the card is created, you can attach the components
       (devices) to the card instance. On ALSA driver, a component is
-      represented as a <type>snd_device_t</type> object.
+      represented as a struct <structname>snd_device</structname> object.
       A component can be a PCM instance, a control interface, a raw
       MIDI interface, etc.  Each of such instances has one component
       entry.
       The chip-specific information, e.g. the i/o port address, its
       resource pointer, or the irq number, is stored in the
       chip-specific record.
-      Usually, the chip-specific record is typedef'ed as
-      <type>xxx_t</type> like the following:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
+  struct mychip {
           ....
   };
 ]]>
           <informalexample>
             <programlisting>
 <![CDATA[
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(mychip_t));
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
 ]]>
             </programlisting>
           </informalexample>
 
-          whether <type>mychip_t</type> is the type of the chip record.
+          whether struct <structname>mychip</structname> is the type of the chip record.
         </para>
 
         <para>
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip = (mychip_t *)card->private_data;
+  struct mychip *chip = card->private_data;
 ]]>
             </programlisting>
           </informalexample>
           After allocating a card instance via
           <function>snd_card_new()</function> (with
           <constant>NULL</constant> on the 4th arg), call
-          <function>kcalloc()</function>. 
+          <function>kzalloc()</function>. 
 
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
-  mychip_t *chip;
+  struct snd_card *card;
+  struct mychip *chip;
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
   .....
-  chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+  chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 ]]>
             </programlisting>
           </informalexample>
           <informalexample>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           ....
   };
 ]]>
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_device_ops_t ops = {
+  static struct snd_device_ops ops = {
           .dev_free =        snd_mychip_dev_free,
   };
   ....
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_mychip_dev_free(snd_device_t *device)
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = device->device_data;
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 ]]>
             </programlisting>
 
       <para>
       For a device which allows hotplugging, you can use
-      <function>snd_card_free_in_thread</function>.  This one will
-      postpone the destruction and wait in a kernel-thread until all
-      devices are closed.
+      <function>snd_card_free_when_closed</function>.  This one will
+      postpone the destruction until all devices are closed.
       </para>
 
     </section>
           <title>PCI Resource Managements Example</title>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           struct pci_dev *pci;
 
           unsigned long port;
           int irq;
   };
 
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           /* disable hardware here if any */
           .... // (not implemented in this document)
 
           /* release the irq */
           if (chip->irq >= 0)
-                  free_irq(chip->irq, (void *)chip);
-          /* release the i/o ports */
+                  free_irq(chip->irq, chip);
+          /* release the i/o ports & memory */
           pci_release_regions(chip->pci);
           /* disable the PCI entry */
           pci_disable_device(chip->pci);
   }
 
   /* chip-specific constructor */
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
           if ((err = pci_enable_device(pci)) < 0)
                   return err;
           /* check PCI availability (28bit DMA) */
-          if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
-              pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
+          if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+              pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
                   printk(KERN_ERR "error to set 28bit mask DMA\n");
                   pci_disable_device(pci);
                   return -ENXIO;
           }
 
-          chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           if (chip == NULL) {
                   pci_disable_device(pci);
                   return -ENOMEM;
           }
           chip->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                          (void *)chip)) {
+                          IRQF_SHARED, "My Chip", chip)) {
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
                   return -EBUSY;
   /* initialization of the module */
   static int __init alsa_card_mychip_init(void)
   {
-          return pci_module_init(&driver);
+          return pci_register_driver(&driver);
   }
 
   /* clean up the module */
         The allocation of PCI resources is done in the
       <function>probe()</function> function, and usually an extra
       <function>xxx_create()</function> function is written for this
-      purpose. 
+      purpose.
       </para>
 
       <para>
       allocating resources. Also, you need to set the proper PCI DMA
       mask to limit the accessed i/o range. In some cases, you might
       need to call <function>pci_set_master()</function> function,
-      too. 
+      too.
       </para>
 
       <para>
 <![CDATA[
   if ((err = pci_enable_device(pci)) < 0)
           return err;
-  if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
-      pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
+  if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+      pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
           printk(KERN_ERR "error to set 28bit mask DMA\n");
           pci_disable_device(pci);
           return -ENXIO;
       functions. Unlike ALSA ver.0.5.x., there are no helpers for
       that. And these resources must be released in the destructor
       function (see below). Also, on ALSA 0.9.x, you don't need to
-      allocate (pseudo-)DMA for PCI like ALSA 0.5.x. 
+      allocate (pseudo-)DMA for PCI like ALSA 0.5.x.
       </para>
 
       <para>
         Now assume that this PCI device has an I/O port with 8 bytes
-        and an interrupt. Then <type>mychip_t</type> will have the
-        following fields: 
+        and an interrupt. Then struct <structname>mychip</structname> will have the
+        following fields:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
 
           unsigned long port;
           int irq;
       need to initialize this number as -1 before actual allocation,
       since irq 0 is valid. The port address and its resource pointer
       can be initialized as null by
-      <function>kcalloc()</function> automatically, so you
+      <function>kzalloc()</function> automatically, so you
       don't have to take care of resetting them. 
       </para>
 
       </para>
 
       <para>
+        <!-- obsolete -->
         It will reserve the i/o port region of 8 bytes of the given
       PCI device. The returned value, chip-&gt;res_port, is allocated
       via <function>kmalloc()</function> by
           <programlisting>
 <![CDATA[
   if (request_irq(pci->irq, snd_mychip_interrupt,
-                  SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                  (void *)chip)) {
+                  IRQF_DISABLED|IRQF_SHARED, "My Chip", chip)) {
           printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
           snd_mychip_free(chip);
           return -EBUSY;
 
       <para>
       On the PCI bus, the interrupts can be shared. Thus,
-      <constant>SA_SHIRQ</constant> is given as the interrupt flag of
+      <constant>IRQF_SHARED</constant> is given as the interrupt flag of
       <function>request_irq()</function>. 
       </para>
 
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           ....
           return IRQ_HANDLED;
   }
           <programlisting>
 <![CDATA[
   if (chip->irq >= 0)
-          free_irq(chip->irq, (void *)chip);
+          free_irq(chip->irq, chip);
 ]]>
           </programlisting>
         </informalexample>
         <informalexample>
           <programlisting>
 <![CDATA[
-  if (chip->res_port) {
-          release_resource(chip->res_port);
-          kfree_nocheck(chip->res_port);
-  }
+  release_and_free_resource(chip->res_port);
 ]]>
           </programlisting>
         </informalexample>
-
-      As you can see, the resource pointer is also to be freed
-      via <function>kfree_nocheck()</function> after
-      <function>release_resource()</function> is called. You
-      cannot use <function>kfree()</function> here, because on ALSA,
-      <function>kfree()</function> may be a wrapper to its own
-      allocator with the memory debugging. Since the resource pointer
-      is allocated externally outside the ALSA, it must be released
-      via the native
-      <function>kfree()</function>.
-      <function>kfree_nocheck()</function> is used for that; it calls
-      the native <function>kfree()</function> without wrapper. 
       </para>
 
       <para>
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
           unsigned long iobase_phys;
           void __iomem *iobase_virt;
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           ....
           if (chip->iobase_virt)
       <title>Registration of Device Struct</title>
       <para>
        At some point, typically after calling <function>snd_device_new()</function>,
-       you need to register the <structname>struct device</structname> of the chip
+       you need to register the struct <structname>device</structname> of the chip
        you're handling for udev and co.  ALSA provides a macro for compatibility with
        older kernels.  Simply call like the following:
         <informalexample>
 <![CDATA[
   static int __init alsa_card_mychip_init(void)
   {
-          return pci_module_init(&driver);
+          return pci_register_driver(&driver);
   }
 
   static void __exit alsa_card_mychip_exit(void)
   ....
 
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
   };
 
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_capture_hw = {
+  static struct snd_pcm_hardware snd_mychip_capture_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
   };
 
   /* open callback */
-  static int snd_mychip_playback_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           // more hardware-initialization will be done here
   }
 
   /* close callback */
-  static int snd_mychip_playback_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* open callback */
-  static int snd_mychip_capture_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_capture_hw;
           // more hardware-initialization will be done here
   }
 
   /* close callback */
-  static int snd_mychip_capture_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* hw_params callback */
-  static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream,
-                               snd_pcm_hw_params_t * hw_params)
+  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params)
   {
           return snd_pcm_lib_malloc_pages(substream,
                                      params_buffer_bytes(hw_params));
   }
 
   /* hw_free callback */
-  static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
   {
           return snd_pcm_lib_free_pages(substream);
   }
 
   /* prepare callback */
-  static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           /* set up the hardware with the current configuration
            * for example...
           mychip_set_sample_format(chip, runtime->format);
           mychip_set_sample_rate(chip, runtime->rate);
           mychip_set_channels(chip, runtime->channels);
-          mychip_set_dma_setup(chip, runtime->dma_area,
+          mychip_set_dma_setup(chip, runtime->dma_addr,
                                chip->buffer_size,
                                chip->period_size);
           return 0;
   }
 
   /* trigger callback */
-  static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream,
+  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
                                     int cmd)
   {
           switch (cmd) {
 
   /* pointer callback */
   static snd_pcm_uframes_t
-  snd_mychip_pcm_pointer(snd_pcm_substream_t *substream)
+  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           unsigned int current_ptr;
 
           /* get the current hardware pointer */
   }
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_playback_open,
           .close =       snd_mychip_playback_close,
           .ioctl =       snd_pcm_lib_ioctl,
   };
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_capture_ops = {
+  static struct snd_pcm_ops snd_mychip_capture_ops = {
           .open =        snd_mychip_capture_open,
           .close =       snd_mychip_capture_close,
           .ioctl =       snd_pcm_lib_ioctl,
    */
 
   /* create a pcm device */
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
           snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                           &snd_mychip_capture_ops);
           /* pre-allocation of buffers */
+          /* NOTE: this may fail */
           snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                                 snd_dma_pci_data(chip->pci),
                                                 64*1024, 64*1024);
     <section id="pcm-interface-constructor">
       <title>Constructor</title>
       <para>
-        A pcm instance is allocated <function>snd_pcm_new()</function>
+        A pcm instance is allocated by <function>snd_pcm_new()</function>
       function. It would be better to create a constructor for pcm,
       namely, 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
       specify more numbers, but they must be handled properly in
       open/close, etc. callbacks.  When you need to know which
       substream you are referring to, then it can be obtained from
-      <type>snd_pcm_substream_t</type> data passed to each callback
+      struct <structname>snd_pcm_substream</structname> data passed to each callback
       as follows: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_substream_t *substream;
+  struct snd_pcm_substream *substream;
   int index = substream->number;
 ]]>
           </programlisting>
         <informalexample>
           <programlisting>
 <![CDATA[
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_pcm_open,
           .close =       snd_mychip_pcm_close,
           .ioctl =       snd_pcm_lib_ioctl,
           <title>PCM Instance with a Destructor</title>
           <programlisting>
 <![CDATA[
-  static void mychip_pcm_free(snd_pcm_t *pcm)
+  static void mychip_pcm_free(struct snd_pcm *pcm)
   {
-          mychip_t *chip = snd_pcm_chip(pcm);
+          struct mychip *chip = snd_pcm_chip(pcm);
           /* free your own data */
           kfree(chip->my_private_pcm_data);
           // do what you like else
           ....
   }
 
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           ....
           /* allocate your own data */
           chip->my_private_pcm_data = kmalloc(...);
 <![CDATA[
 struct _snd_pcm_runtime {
        /* -- Status -- */
-       snd_pcm_substream_t *trigger_master;
+       struct snd_pcm_substream *trigger_master;
        snd_timestamp_t trigger_tstamp; /* trigger timestamp */
        int overrange;
        snd_pcm_uframes_t avail_max;
@@ -2188,8 +2166,7 @@ struct _snd_pcm_runtime {
        unsigned int rate_den;
 
        /* -- SW params -- */
-       int tstamp_timespec;            /* use timeval (0) or timespec (1) */
-       snd_pcm_tstamp_t tstamp_mode;   /* mmap timestamp is updated */
+       struct timespec tstamp_mode;    /* mmap timestamp is updated */
        unsigned int period_step;
        unsigned int sleep_min;         /* min ticks to sleep */
        snd_pcm_uframes_t xfer_align;   /* xfer size need to be a multiple */
@@ -2206,8 +2183,8 @@ struct _snd_pcm_runtime {
        snd_pcm_sync_id_t sync;         /* hardware synchronization ID */
 
        /* -- mmap -- */
-       volatile snd_pcm_mmap_status_t *status;
-       volatile snd_pcm_mmap_control_t *control;
+       volatile struct snd_pcm_mmap_status *status;
+       volatile struct snd_pcm_mmap_control *control;
        atomic_t mmap_count;
 
        /* -- locking / scheduling -- */
@@ -2218,15 +2195,15 @@ struct _snd_pcm_runtime {
 
        /* -- private section -- */
        void *private_data;
-       void (*private_free)(snd_pcm_runtime_t *runtime);
+       void (*private_free)(struct snd_pcm_runtime *runtime);
 
        /* -- hardware description -- */
-       snd_pcm_hardware_t hw;
-       snd_pcm_hw_constraints_t hw_constraints;
+       struct snd_pcm_hardware hw;
+       struct snd_pcm_hw_constraints hw_constraints;
 
        /* -- interrupt callbacks -- */
-       void (*transfer_ack_begin)(snd_pcm_substream_t *substream);
-       void (*transfer_ack_end)(snd_pcm_substream_t *substream);
+       void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
+       void (*transfer_ack_end)(struct snd_pcm_substream *substream);
 
        /* -- timer -- */
        unsigned int timer_resolution;  /* timer resolution */
@@ -2235,11 +2212,12 @@ struct _snd_pcm_runtime {
        unsigned char *dma_area;        /* DMA area */
        dma_addr_t dma_addr;            /* physical bus address (not accessible from main CPU) */
        size_t dma_bytes;               /* size of DMA area */
-       void *dma_private;              /* private DMA data for the memory allocator */
+
+       struct snd_dma_buffer *dma_buffer_p;    /* allocated buffer */
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
        /* -- OSS things -- */
-       snd_pcm_oss_runtime_t oss;
+       struct snd_pcm_oss_runtime oss;
 #endif
 };
 ]]>
@@ -2250,7 +2228,7 @@ struct _snd_pcm_runtime {
        <para>
          For the operators (callbacks) of each sound driver, most of
        these records are supposed to be read-only.  Only the PCM
-       middle-layer changes / updates these info.  The excpetions are
+       middle-layer changes / updates these info.  The exceptions are
        the hardware description (hw), interrupt callbacks
        (transfer_ack_xxx), DMA buffer information, and the private
        data.  Besides, if you use the standard buffer allocation
@@ -2265,7 +2243,7 @@ struct _snd_pcm_runtime {
        <section id="pcm-interface-runtime-hw">
        <title>Hardware Description</title>
        <para>
-         The hardware descriptor (<type>snd_pcm_hardware_t</type>)
+         The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
        contains the definitions of the fundamental hardware
        configuration.  Above all, you'll need to define this in
        <link linkend="pcm-interface-operators-open-callback"><citetitle>
@@ -2280,7 +2258,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct snd_pcm_runtime *runtime = substream->runtime;
           ...
           runtime->hw = snd_mychip_playback_hw; /* common definition */
           if (chip->model == VERY_OLD_ONE)
@@ -2295,7 +2273,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -2350,9 +2328,14 @@ struct _snd_pcm_runtime {
         <constant>PAUSE</constant> bit means that the pcm supports the
         <quote>pause</quote> operation, while the
         <constant>RESUME</constant> bit means that the pcm supports
-        the <quote>suspend/resume</quote> operation. If these flags
-        are set, the <structfield>trigger</structfield> callback below
-        must handle the corresponding commands. 
+        the full <quote>suspend/resume</quote> operation.
+       If <constant>PAUSE</constant> flag is set,
+       the <structfield>trigger</structfield> callback below
+        must handle the corresponding (pause push/release) commands.
+       The suspend/resume trigger commands can be defined even without
+       <constant>RESUME</constant> flag.  See <link
+       linkend="power-management"><citetitle>
+       Power Management</citetitle></link> section for details.
         </para>
 
        <para>
@@ -2525,7 +2508,7 @@ struct _snd_pcm_runtime {
        <title>Running Status</title>
        <para>
        The running status can be referred via <constant>runtime-&gt;status</constant>.
-       This is the pointer to <type>snd_pcm_mmap_status_t</type>
+       This is the pointer to struct <structname>snd_pcm_mmap_status</structname>
        record.  For example, you can get the current DMA hardware
        pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
        </para>
@@ -2533,7 +2516,7 @@ struct _snd_pcm_runtime {
        <para>
        The DMA application pointer can be referred via
        <constant>runtime-&gt;control</constant>, which points
-       <type>snd_pcm_mmap_control_t</type> record.
+       struct <structname>snd_pcm_mmap_control</structname> record.
        However, accessing directly to this value is not recommended.
        </para>
        </section>
@@ -2555,9 +2538,9 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          my_pcm_data_t *data;
+          struct my_pcm_data *data;
           ....
           data = kmalloc(sizeof(*data), GFP_KERNEL);
           substream->runtime->private_data = data;
@@ -2599,7 +2582,7 @@ struct _snd_pcm_runtime {
 
       <para>
         The callback function takes at least the argument with
-        <type>snd_pcm_substream_t</type> pointer. For retrieving the
+        <structname>snd_pcm_substream</structname> pointer. For retrieving the
         chip record from the given substream instance, you can use the
         following macro. 
 
@@ -2607,7 +2590,7 @@ struct _snd_pcm_runtime {
           <programlisting>
 <![CDATA[
   int xxx() {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           ....
   }
 ]]>
@@ -2629,7 +2612,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream);
+  static int snd_xxx_open(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2644,10 +2627,10 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           return 0;
@@ -2680,7 +2663,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream);
+  static int snd_xxx_close(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2695,7 +2678,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream)
+  static int snd_xxx_close(struct snd_pcm_substream *substream)
   {
           ....
           kfree(substream->runtime->private_data);
@@ -2722,8 +2705,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_params(snd_pcm_substream_t * substream,
-                               snd_pcm_hw_params_t * hw_params);
+  static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params);
 ]]>
             </programlisting>
           </informalexample>
@@ -2798,7 +2781,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_free(snd_pcm_substream_t * substream);
+  static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2833,7 +2816,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_prepare(snd_pcm_substream_t * substream);
+  static int snd_xxx_prepare(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2852,7 +2835,7 @@ struct _snd_pcm_runtime {
 
         <para>
        Note that this callback became non-atomic since the recent version.
-       You can use schedule-related fucntions safely in this callback now.
+       You can use schedule-related functions safely in this callback now.
         </para>
 
         <para>
@@ -2882,7 +2865,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd);
+  static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
 ]]>
             </programlisting>
           </informalexample>
@@ -2924,8 +2907,8 @@ struct _snd_pcm_runtime {
         </para>
 
         <para>
-          When the pcm supports the suspend/resume operation
-        (i.e. <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set),
+          When the pcm supports the suspend/resume operation,
+       regardless of full or partial suspend/resume support,
         <constant>SUSPEND</constant> and <constant>RESUME</constant>
         commands must be handled, too.
         These commands are issued when the power-management status is
@@ -2934,6 +2917,8 @@ struct _snd_pcm_runtime {
         do suspend and resume of the pcm substream, and usually, they
         are identical with <constant>STOP</constant> and
         <constant>START</constant> commands, respectively.
+         See <link linkend="power-management"><citetitle>
+       Power Management</citetitle></link> section for details.
         </para>
 
         <para>
@@ -2952,7 +2937,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream)
+  static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
 ]]>
             </programlisting>
           </informalexample>
@@ -3008,6 +2993,9 @@ struct _snd_pcm_runtime {
        current appl_ptr for the internal buffer, and this callback
        is useful only for such a purpose.
        </para>
+       <para>
+         This callback is atomic.
+       </para>
       </section>
 
       <section id="pcm-interface-operators-page-callback">
@@ -3059,7 +3047,7 @@ struct _snd_pcm_runtime {
         </para>
 
         <para>
-          If you aquire a spinlock in the interrupt handler, and the
+          If you acquire a spinlock in the interrupt handler, and the
         lock is used in other pcm callbacks, too, then you have to
         release the lock before calling
         <function>snd_pcm_period_elapsed()</function>, because
@@ -3077,7 +3065,7 @@ struct _snd_pcm_runtime {
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
@@ -3121,7 +3109,7 @@ struct _snd_pcm_runtime {
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
@@ -3205,6 +3193,11 @@ struct _snd_pcm_runtime {
       <function>udelay()</function> or <function>mdelay()</function>.
       </para>
 
+      <para>
+      All three atomic callbacks (trigger, pointer, and ack) are
+      called with local interrupts disabled.
+      </para>
+
     </section>
     <section id="pcm-interface-constraints">
       <title>Constraints</title>
@@ -3226,13 +3219,13 @@ struct _snd_pcm_runtime {
 <![CDATA[
   static unsigned int rates[] =
           {4000, 10000, 22050, 44100};
-  static snd_pcm_hw_constraint_list_t constraints_rates = {
+  static struct snd_pcm_hw_constraint_list constraints_rates = {
           .count = ARRAY_SIZE(rates),
           .list = rates,
           .mask = 0,
   };
 
-  static int snd_mychip_pcm_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
   {
           int err;
           ....
@@ -3250,23 +3243,24 @@ struct _snd_pcm_runtime {
 
       <para>
         There are many different constraints.
-        Look in <filename>sound/asound.h</filename> for a complete list.
+        Look in <filename>sound/pcm.h</filename> for a complete list.
         You can even define your own constraint rules.
         For example, let's suppose my_chip can manage a substream of 1 channel
         if and only if the format is S16_LE, otherwise it supports any format
-        specified in the <type>snd_pcm_hardware_t</type> stucture (or in any
+        specified in the <structname>snd_pcm_hardware</structname> stucture (or in any
         other constraint_list). You can build a rule like this:
 
         <example>
          <title>Example of Hardware Constraints for Channels</title>
          <programlisting>
 <![CDATA[
-  static int hw_rule_format_by_channels(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_mask_t fmt;
+          struct snd_interval *c = hw_param_interval(params,
+                SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_mask fmt;
 
           snd_mask_any(&fmt);    /* Init the struct */
           if (c->min < 2) {
@@ -3303,12 +3297,13 @@ struct _snd_pcm_runtime {
         <title>Example of Hardware Constraints for Channels</title>
         <programlisting>
 <![CDATA[
-  static int hw_rule_channels_by_format(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_interval_t ch;
+          struct snd_interval *c = hw_param_interval(params,
+                        SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_interval ch;
 
           snd_interval_any(&ch);
           if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
@@ -3381,18 +3376,18 @@ struct _snd_pcm_runtime {
       callbacks: <structfield>info</structfield>,
       <structfield>get</structfield> and
       <structfield>put</structfield>. Then, define a
-      <type>snd_kcontrol_new_t</type> record, such as: 
+      struct <structname>snd_kcontrol_new</structname> record, such as: 
 
         <example>
          <title>Definition of a Control</title>
           <programlisting>
 <![CDATA[
-  static snd_kcontrol_new_t my_control __devinitdata = {
+  static struct snd_kcontrol_new my_control __devinitdata = {
           .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
           .name = "PCM Playback Switch",
           .index = 0,
           .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-          .private_values = 0xffff,
+          .private_value = 0xffff,
           .info = my_control_info,
           .get = my_control_get,
           .put = my_control_put
@@ -3411,10 +3406,17 @@ struct _snd_pcm_runtime {
 
       <para>
         The <structfield>iface</structfield> field specifies the type of
-      the control,
-      <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are
-      <constant>MIXER</constant>, <constant>PCM</constant>,
-      <constant>CARD</constant>, etc.
+      the control, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
+      is usually <constant>MIXER</constant>.
+      Use <constant>CARD</constant> for global controls that are not
+      logically part of the mixer.
+      If the control is closely associated with some specific device on
+      the sound card, use <constant>HWDEP</constant>,
+      <constant>PCM</constant>, <constant>RAWMIDI</constant>,
+      <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
+      specify the device number with the
+      <structfield>device</structfield> and
+      <structfield>subdevice</structfield> fields.
       </para>
 
       <para>
@@ -3446,7 +3448,7 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
-        The <structfield>private_values</structfield> field contains
+        The <structfield>private_value</structfield> field contains
       an arbitrary long integer value for this record. When using
       generic <structfield>info</structfield>,
       <structfield>get</structfield> and
@@ -3597,7 +3599,7 @@ struct _snd_pcm_runtime {
         <para>
           The <structfield>info</structfield> callback is used to get
         the detailed information of this control. This must store the
-        values of the given <type>snd_ctl_elem_info_t</type>
+        values of the given struct <structname>snd_ctl_elem_info</structname>
         object. For example, for a boolean control with a single
         element will be: 
 
@@ -3605,8 +3607,8 @@ struct _snd_pcm_runtime {
            <title>Example of info callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
           uinfo->count = 1;
@@ -3640,8 +3642,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           static char *texts[4] = {
                   "First", "Second", "Third", "Fourth"
@@ -3676,10 +3678,10 @@ struct _snd_pcm_runtime {
            <title>Example of get callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_get(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           ucontrol->value.integer.value[0] = get_some_value(chip);
           return 0;
   }
@@ -3691,8 +3693,7 @@ struct _snd_pcm_runtime {
         <para>
           Here, the chip instance is retrieved via
         <function>snd_kcontrol_chip()</function> macro.  This macro
-        converts from kcontrol-&gt;private_data to the type defined by
-        <type>chip_t</type>. The
+        just accesses to kcontrol-&gt;private_data. The
         kcontrol-&gt;private_data field is 
         given as the argument of <function>snd_ctl_new()</function>
         (see the later subsection
@@ -3716,8 +3717,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_sbmixer_get_single(snd_kcontrol_t *kcontrol,
-                                    snd_ctl_elem_value_t *ucontrol)
+  static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
   {
           int reg = kcontrol->private_value & 0xff;
           int shift = (kcontrol->private_value >> 16) & 0xff;
@@ -3753,10 +3754,10 @@ struct _snd_pcm_runtime {
            <title>Example of put callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_put(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_put(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           int changed = 0;
           if (chip->current_value !=
                ucontrol->value.integer.value[0]) {
@@ -3813,7 +3814,7 @@ struct _snd_pcm_runtime {
         </informalexample>
 
         where <parameter>my_control</parameter> is the
-      <type>snd_kcontrol_new_t</type> object defined above, and chip
+      struct <structname>snd_kcontrol_new</structname> object defined above, and chip
       is the object pointer to be passed to
       kcontrol-&gt;private_data 
       which can be referred in callbacks. 
@@ -3821,7 +3822,7 @@ struct _snd_pcm_runtime {
 
       <para>
         <function>snd_ctl_new1()</function> allocates a new
-      <type>snd_kcontrol_t</type> instance (that's why the definition
+      <structname>snd_kcontrol</structname> instance (that's why the definition
       of <parameter>my_control</parameter> can be with
       <parameter>__devinitdata</parameter> 
       prefix), and <function>snd_ctl_add</function> assigns the given
@@ -3848,7 +3849,7 @@ struct _snd_pcm_runtime {
       control id pointer for the notification. The event-mask
       specifies the types of notification, for example, in the above
       example, the change of control values is notified.
-      The id pointer is the pointer of <type>snd_ctl_elem_id_t</type>
+      The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
       to be notified.
       You can find some examples in <filename>es1938.c</filename> or
       <filename>es1968.c</filename> for hardware volume interrupts. 
@@ -3881,35 +3882,35 @@ struct _snd_pcm_runtime {
            <title>Example of AC97 Interface</title>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
-          ac97_t *ac97;
+          struct snd_ac97 *ac97;
           ....
   };
 
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           // read a register value here from the codec
           return the_register_value;
   }
 
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                                    unsigned short reg, unsigned short val)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           // write the given register value to the codec
   }
 
-  static int snd_mychip_ac97(mychip_t *chip)
+  static int snd_mychip_ac97(struct mychip *chip)
   {
-          ac97_bus_t *bus;
-          ac97_template_t ac97;
+          struct snd_ac97_bus *bus;
+          struct snd_ac97_template ac97;
           int err;
-          static ac97_bus_ops_t ops = {
+          static struct snd_ac97_bus_ops ops = {
                   .write = snd_mychip_ac97_write,
                   .read = snd_mychip_ac97_read,
           };
@@ -3936,8 +3937,8 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_bus_t *bus;
-  static ac97_bus_ops_t ops = {
+  struct snd_ac97_bus *bus;
+  static struct snd_ac97_bus_ops ops = {
         .write = snd_mychip_ac97_write,
         .read = snd_mychip_ac97_read,
   };
@@ -3951,13 +3952,14 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
-      And then call <function>snd_ac97_mixer()</function> with an <type>ac97_template_t</type>
+      And then call <function>snd_ac97_mixer()</function> with an
+      struct <structname>snd_ac97_template</structname>
       record together with the bus pointer created above.
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_template_t ac97;
+  struct snd_ac97_template ac97;
   int err;
 
   memset(&ac97, 0, sizeof(ac97));
@@ -3994,10 +3996,10 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           return the_register_value;
   }
@@ -4015,7 +4017,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                        unsigned short reg, unsigned short val)
 ]]>
           </programlisting>
@@ -4066,7 +4068,7 @@ struct _snd_pcm_runtime {
         Both <function>snd_ac97_write()</function> and
         <function>snd_ac97_update()</function> functions are used to
         set a value to the given register
-        (<constant>AC97_XXX</constant>). The different between them is
+        (<constant>AC97_XXX</constant>). The difference between them is
         that <function>snd_ac97_update()</function> doesn't write a
         value if the given value has been already set, while
         <function>snd_ac97_write()</function> always rewrites the
@@ -4152,8 +4154,8 @@ struct _snd_pcm_runtime {
       <title>Proc Files</title>
       <para>
         The ALSA AC97 interface will create a proc file such as
-      <filename>/proc/asound/card0/ac97#0</filename> and
-      <filename>ac97#0regs</filename>. You can refer to these files to
+      <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
+      <filename>ac97#0-0+regs</filename>. You can refer to these files to
       see the current status and registers of the codec. 
       </para>
     </section>
@@ -4162,7 +4164,7 @@ struct _snd_pcm_runtime {
       <title>Multiple Codecs</title>
       <para>
         When there are several codecs on the same card, you need to
-      call <function>snd_ac97_new()</function> multiple times with
+      call <function>snd_ac97_mixer()</function> multiple times with
       ac97.num=1 or greater. The <structfield>num</structfield> field
       specifies the codec 
       number. 
@@ -4200,18 +4202,6 @@ struct _snd_pcm_runtime {
       implementation of mpu401 stuff. For example, emu10k1 has its own
       mpu401 routines. 
       </para>
-
-      <para>
-        In this document, I won't explain the rawmidi interface API,
-      which is the basis of MPU401-UART implementation. 
-      </para>
-
-      <para>
-        For details, please check the source,
-      <filename>core/rawmidi.c</filename>, and examples such as
-      <filename>drivers/mpu401/mpu401_uart.c</filename> or
-      <filename>usb/usbmidi.c</filename>. 
-      </para>
     </section>
 
     <section id="midi-interface-constructor">
@@ -4223,8 +4213,8 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_rawmidi_t *rmidi;
-  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
+  struct snd_rawmidi *rmidi;
+  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
                       irq, irq_flags, &rmidi);
 ]]>
           </programlisting>
@@ -4251,30 +4241,51 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
+       The 5th argument is bitflags for additional information.
         When the i/o port address above is a part of the PCI i/o
       region, the MPU401 i/o port might have been already allocated
-      (reserved) by the driver itself. In such a case, pass non-zero
-      to the 5th argument
-      (<parameter>integrated</parameter>). Otherwise, pass 0 to it,
+      (reserved) by the driver itself. In such a case, pass a bit flag
+      <constant>MPU401_INFO_INTEGRATED</constant>,
       and 
       the mpu401-uart layer will allocate the i/o ports by itself. 
       </para>
 
+       <para>
+       When the controller supports only the input or output MIDI stream,
+       pass <constant>MPU401_INFO_INPUT</constant> or
+       <constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
+       Then the rawmidi instance is created as a single stream.
+       </para>
+
+       <para>
+       <constant>MPU401_INFO_MMIO</constant> bitflag is used to change
+       the access method to MMIO (via readb and writeb) instead of
+       iob and outb.  In this case, you have to pass the iomapped address
+       to <function>snd_mpu401_uart_new()</function>.
+       </para>
+
+       <para>
+       When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
+       stream isn't checked in the default interrupt handler.  The driver
+       needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
+       by itself to start processing the output stream in irq handler.
+       </para>
+
       <para>
         Usually, the port address corresponds to the command port and
         port + 1 corresponds to the data port. If not, you may change
         the <structfield>cport</structfield> field of
-        <type>mpu401_t</type> manually 
-        afterward. However, <type>mpu401_t</type> pointer is not
+        struct <structname>snd_mpu401</structname> manually 
+        afterward. However, <structname>snd_mpu401</structname> pointer is not
         returned explicitly by
         <function>snd_mpu401_uart_new()</function>. You need to cast
         rmidi-&gt;private_data to
-        <type>mpu401_t</type> explicitly, 
+        <structname>snd_mpu401</structname> explicitly, 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  mpu401_t *mpu;
+  struct snd_mpu401 *mpu;
   mpu = rmidi->private_data;
 ]]>
           </programlisting>
@@ -4334,6 +4345,354 @@ struct _snd_pcm_runtime {
   </chapter>
 
 
+<!-- ****************************************************** -->
+<!-- RawMIDI Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="rawmidi-interface">
+    <title>RawMIDI Interface</title>
+
+    <section id="rawmidi-interface-overview">
+      <title>Overview</title>
+
+      <para>
+      The raw MIDI interface is used for hardware MIDI ports that can
+      be accessed as a byte stream.  It is not used for synthesizer
+      chips that do not directly understand MIDI.
+      </para>
+
+      <para>
+      ALSA handles file and buffer management.  All you have to do is
+      to write some code to move data between the buffer and the
+      hardware.
+      </para>
+
+      <para>
+      The rawmidi API is defined in
+      <filename>&lt;sound/rawmidi.h&gt;</filename>.
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-constructor">
+      <title>Constructor</title>
+
+      <para>
+      To create a rawmidi device, call the
+      <function>snd_rawmidi_new</function> function:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi *rmidi;
+  err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
+  if (err < 0)
+          return err;
+  rmidi->private_data = chip;
+  strcpy(rmidi->name, "My MIDI");
+  rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+                      SNDRV_RAWMIDI_INFO_INPUT |
+                      SNDRV_RAWMIDI_INFO_DUPLEX;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The first argument is the card pointer, the second argument is
+      the ID string.
+      </para>
+
+      <para>
+      The third argument is the index of this component.  You can
+      create up to 8 rawmidi devices.
+      </para>
+
+      <para>
+      The fourth and fifth arguments are the number of output and
+      input substreams, respectively, of this device.  (A substream is
+      the equivalent of a MIDI port.)
+      </para>
+
+      <para>
+      Set the <structfield>info_flags</structfield> field to specify
+      the capabilities of the device.
+      Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is
+      at least one output port,
+      <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at
+      least one input port,
+      and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device
+      can handle output and input at the same time.
+      </para>
+
+      <para>
+      After the rawmidi device is created, you need to set the
+      operators (callbacks) for each substream.  There are helper
+      functions to set the operators for all substream of a device:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The operators are usually defined like this:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
+          .open =    snd_mymidi_output_open,
+          .close =   snd_mymidi_output_close,
+          .trigger = snd_mymidi_output_trigger,
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      These callbacks are explained in the <link
+      linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link>
+      section.
+      </para>
+
+      <para>
+      If there is more than one substream, you should give each one a
+      unique name:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct list_head *list;
+  struct snd_rawmidi_substream *substream;
+  list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
+          substream = list_entry(list, struct snd_rawmidi_substream, list);
+          sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
+  }
+  /* same for SNDRV_RAWMIDI_STREAM_INPUT */
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-callbacks">
+      <title>Callbacks</title>
+
+      <para>
+      In all callbacks, the private data that you've set for the
+      rawmidi device can be accessed as
+      substream-&gt;rmidi-&gt;private_data.
+      <!-- <code> isn't available before DocBook 4.3 -->
+      </para>
+
+      <para>
+      If there is more than one port, your callbacks can determine the
+      port index from the struct snd_rawmidi_substream data passed to each
+      callback:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi_substream *substream;
+  int index = substream->number;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <section id="rawmidi-interface-op-open">
+      <title><function>open</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called when a substream is opened.
+        You can initialize the hardware here, but you should not yet
+        start transmitting/receiving data.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-close">
+      <title><function>close</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_close(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        Guess what.
+        </para>
+
+        <para>
+        The <function>open</function> and <function>close</function>
+        callbacks of a rawmidi device are serialized with a mutex,
+        and can sleep.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-out">
+      <title><function>trigger</function> callback for output
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter when there is some data in the substream buffer that
+        must be transmitted.
+        </para>
+
+        <para>
+        To read data from the buffer, call
+        <function>snd_rawmidi_transmit_peek</function>.  It will
+        return the number of bytes that have been read; this will be
+        less than the number of bytes requested when there is no more
+        data in the buffer.
+        After the data has been transmitted successfully, call
+        <function>snd_rawmidi_transmit_ack</function> to remove the
+        data from the substream buffer:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  unsigned char data;
+  while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
+          if (snd_mychip_try_to_transmit(data))
+                  snd_rawmidi_transmit_ack(substream, 1);
+          else
+                  break; /* hardware FIFO full */
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand that the hardware will accept data, you
+        can use the <function>snd_rawmidi_transmit</function> function
+        which reads some data and removes it from the buffer at once:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  while (snd_mychip_transmit_possible()) {
+          unsigned char data;
+          if (snd_rawmidi_transmit(substream, &data, 1) != 1)
+                  break; /* no more data */
+          snd_mychip_transmit(data);
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand how many bytes you can accept, you can
+        use a buffer size greater than one with the
+        <function>snd_rawmidi_transmit*</function> functions.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep.  If
+        the hardware FIFO is full before the substream buffer has been
+        emptied, you have to continue transmitting data later, either
+        in an interrupt handler, or with a timer if the hardware
+        doesn't have a MIDI transmit interrupt.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback is called with a
+        zero <parameter>up</parameter> parameter when the transmission
+        of data should be aborted.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-in">
+      <title><function>trigger</function> callback for input
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter to enable receiving data, or with a zero
+        <parameter>up</parameter> parameter do disable receiving data.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep; the
+        actual reading of data from the device is usually done in an
+        interrupt handler.
+        </para>
+
+        <para>
+        When data reception is enabled, your interrupt handler should
+        call <function>snd_rawmidi_receive</function> for all received
+        data:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  void snd_mychip_midi_interrupt(...)
+  {
+          while (mychip_midi_available()) {
+                  unsigned char data;
+                  data = mychip_midi_read();
+                  snd_rawmidi_receive(substream, &data, 1);
+          }
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-drain">
+      <title><function>drain</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is only used with output substreams.  This function should wait
+        until all data read from the substream buffer has been transmitted.
+        This ensures that the device can be closed and the driver unloaded
+        without losing data.
+        </para>
+
+        <para>
+        This callback is optional.  If you do not set
+        <structfield>drain</structfield> in the struct snd_rawmidi_ops
+        structure, ALSA will simply wait for 50&nbsp;milliseconds
+        instead.
+        </para>
+      </section>
+    </section>
+
+  </chapter>
+
+
 <!-- ****************************************************** -->
 <!-- Miscellaneous Devices  -->
 <!-- ****************************************************** -->
@@ -4366,7 +4725,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  opl3_t *opl3;
+  struct snd_opl3 *opl3;
   snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
                   integrated, &opl3);
 ]]>
@@ -4399,7 +4758,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  opl3_t *opl3;
+  struct snd_opl3 *opl3;
   snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
 ]]>
           </programlisting>
@@ -4430,7 +4789,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *opl3hwdep;
+  struct snd_hwdep *opl3hwdep;
   snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
 ]]>
           </programlisting>
@@ -4467,7 +4826,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *hw;
+  struct snd_hwdep *hw;
   snd_hwdep_new(card, "My HWDEP", 0, &hw);
 ]]>
           </programlisting>
@@ -4486,7 +4845,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  mydata_t *p = kmalloc(sizeof(*p), GFP_KERNEL);
+  struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
   hw->private_data = p;
   hw->private_free = mydata_free;
 ]]>
@@ -4498,9 +4857,9 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void mydata_free(snd_hwdep_t *hw)
+  static void mydata_free(struct snd_hwdep *hw)
   {
-          mydata_t *p = hw->private_data;
+          struct mydata *p = hw->private_data;
           kfree(p);
   }
 ]]>
@@ -4633,7 +4992,7 @@ struct _snd_pcm_runtime {
         where <parameter>size</parameter> is the byte size to be
       pre-allocated and the <parameter>max</parameter> is the maximal
       size to be changed via <filename>prealloc</filename> proc file.
-      The allocator will try to get as the large area as possible
+      The allocator will try to get as large area as possible
       within the given size. 
       </para>
 
@@ -4724,9 +5083,9 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int playback_copy(snd_pcm_substream_t *substream, int channel,
+  static int playback_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
-  static int capture_copy(snd_pcm_substream_t *substream, int channel,
+  static int capture_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -4807,7 +5166,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int silence(snd_pcm_substream_t *substream, int channel,
+  static int silence(struct snd_pcm_substream *substream, int channel,
                      snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -4855,7 +5214,7 @@ struct _snd_pcm_runtime {
         If your hardware supports the page table like emu10k1 or the
       buffer descriptors like via82xx, you can use the scatter-gather
       (SG) DMA. ALSA provides an interface for handling SG-buffers.
-      The API is provided in <filename>&lt;sound/pcm_sgbuf.h&gt;</filename>. 
+      The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>. 
       </para>
 
       <para>
@@ -4867,14 +5226,14 @@ struct _snd_pcm_runtime {
         You need to pass the <function>snd_dma_pci_data(pci)</function>,
         where pci is the struct <structname>pci_dev</structname> pointer
         of the chip as well.
-        The <type>snd_sg_buf_t</type> instance is created as
+        The <type>struct snd_sg_buf</type> instance is created as
         substream-&gt;dma_private. You can cast
         the pointer like: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private;
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
 ]]>
           </programlisting>
         </informalexample>
@@ -4929,7 +5288,7 @@ struct _snd_pcm_runtime {
   #include <linux/vmalloc.h>
 
   /* get the physical page pointer on the given offset */
-  static struct page *mychip_page(snd_pcm_substream_t *substream,
+  static struct page *mychip_page(struct snd_pcm_substream *substream,
                                   unsigned long offset)
   {
           void *pageptr = substream->runtime->dma_area + offset;
@@ -4964,7 +5323,7 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  snd_info_entry_t *entry;
+  struct snd_info_entry *entry;
   int err = snd_card_proc_new(card, "my-file", &entry);
 ]]>
         </programlisting>
@@ -4994,7 +5353,7 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  snd_info_set_text_ops(entry, chip, read_size, my_proc_read);
+  snd_info_set_text_ops(entry, chip, my_proc_read);
 ]]>
         </programlisting>
       </informalexample>
@@ -5008,8 +5367,8 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer);
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer);
 ]]>
         </programlisting>
       </informalexample>
@@ -5024,10 +5383,10 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer)
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer)
   {
-          chip_t *chip = entry->private_data;
+          struct my_chip *chip = entry->private_data;
 
           snd_iprintf(buffer, "This is my chip!\n");
           snd_iprintf(buffer, "Port = %ld\n", chip->port);
@@ -5055,29 +5414,12 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  entry->c.text.write_size = 256;
   entry->c.text.write = my_proc_write;
 ]]>
         </programlisting>
       </informalexample>
     </para>
 
-    <para>
-    The buffer size for read is set to 1024 implicitly by
-    <function>snd_info_set_text_ops()</function>.  It should suffice
-    in most cases (the size will be aligned to
-    <constant>PAGE_SIZE</constant> anyway), but if you need to handle
-    very large text files, you can set it explicitly, too.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  entry->c.text.read_size = 65536;
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
     <para>
       For the write callback, you can use
     <function>snd_info_get_line()</function> to get a text line, and
@@ -5116,7 +5458,7 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static long my_file_io_read(snd_info_entry_t *entry,
+  static long my_file_io_read(struct snd_info_entry *entry,
                               void *file_private_data,
                               struct file *file,
                               char *buf,
@@ -5144,29 +5486,67 @@ struct _snd_pcm_runtime {
   <chapter id="power-management">
     <title>Power Management</title>
     <para>
-      If the chip is supposed to work with with suspend/resume
+      If the chip is supposed to work with suspend/resume
       functions, you need to add the power-management codes to the
       driver. The additional codes for the power-management should be
       <function>ifdef</function>'ed with
       <constant>CONFIG_PM</constant>. 
     </para>
 
+       <para>
+       If the driver supports the suspend/resume
+       <emphasis>fully</emphasis>, that is, the device can be
+       properly resumed to the status at the suspend is called,
+       you can set <constant>SNDRV_PCM_INFO_RESUME</constant> flag
+       to pcm info field.  Usually, this is possible when the
+       registers of ths chip can be safely saved and restored to the
+       RAM.  If this is set, the trigger callback is called with
+       <constant>SNDRV_PCM_TRIGGER_RESUME</constant> after resume
+       callback is finished. 
+       </para>
+
+       <para>
+       Even if the driver doesn't support PM fully but only the
+       partial suspend/resume is possible, it's still worthy to
+       implement suspend/resume callbacks.  In such a case, applications
+       would reset the status by calling
+       <function>snd_pcm_prepare()</function> and restart the stream
+       appropriately.  Hence, you can define suspend/resume callbacks
+       below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
+       info flag to the PCM.
+       </para>
+       
+       <para>
+       Note that the trigger with SUSPEND can be always called when
+       <function>snd_pcm_suspend_all</function> is called,
+       regardless of <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
+       The <constant>RESUME</constant> flag affects only the behavior
+       of <function>snd_pcm_resume()</function>.
+       (Thus, in theory,
+       <constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
+       to be handled in the trigger callback when no
+       <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set.  But,
+       it's better to keep it for compatibility reason.)
+       </para>
     <para>
-      ALSA provides the common power-management layer. Each card driver
-      needs to have only low-level suspend and resume callbacks.
+      In the earlier version of ALSA drivers, a common
+      power-management layer was provided, but it has been removed.
+      The driver needs to define the suspend/resume hooks according to
+      the bus the device is assigned.  In the case of PCI driver, the
+      callbacks look like below:
 
       <informalexample>
         <programlisting>
 <![CDATA[
   #ifdef CONFIG_PM
-  static int snd_my_suspend(snd_card_t *card, unsigned int state)
+  static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
   {
-          .... // do things for suspsend
+          .... /* do things for suspsend */
           return 0;
   }
-  static int snd_my_resume(snd_card_t *card, unsigned int state)
+  static int snd_my_resume(struct pci_dev *pci)
   {
-          .... // do things for suspsend
+          .... /* do things for suspsend */
           return 0;
   }
   #endif
@@ -5179,11 +5559,18 @@ struct _snd_pcm_runtime {
       The scheme of the real suspend job is as following.
 
       <orderedlist>
-        <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem>
+        <listitem><para>Retrieve the card and the chip data.</para></listitem>
+        <listitem><para>Call <function>snd_power_change_state()</function> with
+         <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
+         power status.</para></listitem>
         <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
+       <listitem><para>If AC97 codecs are used, call
+       <function>snd_ac97_suspend()</function> for each codec.</para></listitem>
         <listitem><para>Save the register values if necessary.</para></listitem>
         <listitem><para>Stop the hardware if necessary.</para></listitem>
-        <listitem><para>Disable the PCI device by calling <function>pci_disable_device()</function>.</para></listitem>
+        <listitem><para>Disable the PCI device by calling
+         <function>pci_disable_device()</function>.  Then, call
+          <function>pci_save_state()</function> at last.</para></listitem>
       </orderedlist>
     </para>
 
@@ -5193,18 +5580,24 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static int mychip_suspend(snd_card_t *card, unsigned int state)
+  static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
   {
           /* (1) */
-          mychip_t *chip = card->pm_private_data;
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
           /* (2) */
-          snd_pcm_suspend_all(chip->pcm);
+          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
           /* (3) */
-          snd_mychip_save_registers(chip);
+          snd_pcm_suspend_all(chip->pcm);
           /* (4) */
-          snd_mychip_stop_hardware(chip);
+          snd_ac97_suspend(chip->ac97);
           /* (5) */
-          pci_disable_device(chip->pci);
+          snd_mychip_save_registers(chip);
+          /* (6) */
+          snd_mychip_stop_hardware(chip);
+          /* (7) */
+          pci_disable_device(pci);
+          pci_save_state(pci);
           return 0;
   }
 ]]>
@@ -5216,14 +5609,17 @@ struct _snd_pcm_runtime {
     The scheme of the real resume job is as following.
 
     <orderedlist>
-    <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem>
-    <listitem><para>Enable the pci device again by calling
-    <function>pci_enable_device()</function>.</para></listitem>
+    <listitem><para>Retrieve the card and the chip data.</para></listitem>
+    <listitem><para>Set up PCI.  First, call <function>pci_restore_state()</function>.
+       Then enable the pci device again by calling <function>pci_enable_device()</function>.
+       Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
     <listitem><para>Re-initialize the chip.</para></listitem>
     <listitem><para>Restore the saved registers if necessary.</para></listitem>
     <listitem><para>Resume the mixer, e.g. calling
     <function>snd_ac97_resume()</function>.</para></listitem>
     <listitem><para>Restart the hardware (if any).</para></listitem>
+    <listitem><para>Call <function>snd_power_change_state()</function> with
+       <constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
     </orderedlist>
     </para>
 
@@ -5233,12 +5629,15 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void mychip_resume(mychip_t *chip)
+  static int mychip_resume(struct pci_dev *pci)
   {
           /* (1) */
-          mychip_t *chip = card->pm_private_data;
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
           /* (2) */
-          pci_enable_device(chip->pci);
+          pci_restore_state(pci);
+          pci_enable_device(pci);
+          pci_set_master(pci);
           /* (3) */
           snd_mychip_reinit_chip(chip);
           /* (4) */
@@ -5247,6 +5646,8 @@ struct _snd_pcm_runtime {
           snd_ac97_resume(chip->ac97);
           /* (6) */
           snd_mychip_restart_chip(chip);
+          /* (7) */
+          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
           return 0;
   }
 ]]>
@@ -5255,8 +5656,48 @@ struct _snd_pcm_runtime {
     </para>
 
     <para>
-      OK, we have all callbacks now. Let's set up them now. In the
-      initialization of the card, add the following: 
+       As shown in the above, it's better to save registers after
+       suspending the PCM operations via
+       <function>snd_pcm_suspend_all()</function> or
+       <function>snd_pcm_suspend()</function>.  It means that the PCM
+       streams are already stoppped when the register snapshot is
+       taken.  But, remind that you don't have to restart the PCM
+       stream in the resume callback. It'll be restarted via 
+       trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
+       when necessary.
+    </para>
+
+    <para>
+      OK, we have all callbacks now. Let's set them up. In the
+      initialization of the card, make sure that you can get the chip
+      data from the card instance, typically via
+      <structfield>private_data</structfield> field, in case you
+      created the chip data individually.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          ....
+          struct snd_card *card;
+          struct mychip *chip;
+          ....
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+          ....
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          ....
+          card->private_data = chip;
+          ....
+  }
+]]>
+        </programlisting>
+      </informalexample>
+
+       When you created the chip data with
+       <function>snd_card_new()</function>, it's anyway accessible
+       via <structfield>private_data</structfield> field.
 
       <informalexample>
         <programlisting>
@@ -5265,33 +5706,31 @@ struct _snd_pcm_runtime {
                                const struct pci_device_id *pci_id)
   {
           ....
-          snd_card_t *card;
-          mychip_t *chip;
+          struct snd_card *card;
+          struct mychip *chip;
+          ....
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+                              sizeof(struct mychip));
           ....
-          snd_card_set_pm_callback(card, snd_my_suspend, snd_my_resume, chip);
+          chip = card->private_data;
           ....
   }
 ]]>
         </programlisting>
       </informalexample>
 
-    Here you don't have to put ifdef CONFIG_PM around, since it's already
-    checked in the header and expanded to empty if not needed.
     </para>
 
     <para>
-      If you need a space for saving the registers, you'll need to
-    allocate the buffer for it here, too, since it would be fatal
+      If you need a space for saving the registers, allocate the
+       buffer for it here, too, since it would be fatal
     if you cannot allocate a memory in the suspend phase.
     The allocated buffer should be released in the corresponding
     destructor.
     </para>
 
     <para>
-      And next, set suspend/resume callbacks to the pci_driver,
-      This can be done by passing a macro SND_PCI_PM_CALLBACKS
-      in the pci_driver struct.  This macro is expanded to the correct
-      (global) callbacks if CONFIG_PM is set.
+      And next, set suspend/resume callbacks to the pci_driver.
 
       <informalexample>
         <programlisting>
@@ -5301,7 +5740,10 @@ struct _snd_pcm_runtime {
           .id_table = snd_my_ids,
           .probe = snd_my_probe,
           .remove = __devexit_p(snd_my_remove),
-          SND_PCI_PM_CALLBACKS
+  #ifdef CONFIG_PM
+          .suspend = snd_my_suspend,
+          .resume = snd_my_resume,
+  #endif
   };
 ]]>
         </programlisting>
@@ -5644,32 +6086,23 @@ struct _snd_pcm_runtime {
         The first argument is the expression to evaluate, and the
       second argument is the action if it fails. When
       <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
-      error message such as <computeroutput>BUG? (xxx) (called from
-      yyy)</computeroutput>. When no debug flag is set, this is
-      ignored. 
+      error message such as <computeroutput>BUG? (xxx)</computeroutput>
+      together with stack trace.
       </para>
-    </section>
-
-    <section id="useful-functions-snd-runtime-check">
-      <title><function>snd_runtime_check()</function></title>
       <para>
-        This macro is quite similar with
-      <function>snd_assert()</function>. Unlike
-      <function>snd_assert()</function>, the expression is always
-      evaluated regardless of
-      <constant>CONFIG_SND_DEBUG</constant>. When
-      <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
-      show a message like <computeroutput>ERROR (xx) (called from
-      yyy)</computeroutput>. 
+        When no debug flag is set, this macro is ignored. 
       </para>
     </section>
 
     <section id="useful-functions-snd-bug">
       <title><function>snd_BUG()</function></title>
       <para>
-        It calls <function>snd_assert(0,)</function> -- that is, just
-      prints the error message at the point. It's useful to show that
-      a fatal error happens there. 
+        It shows <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_assert</function> at the point.
+      It's useful to show that a fatal error happens there. 
+      </para>
+      <para>
+        When no debug flag is set, this macro is ignored. 
       </para>
     </section>
   </chapter>