fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / Documentation / sound / alsa / DocBook / writing-an-alsa-driver.tmpl
index 4251085..ccd0a95 100644 (file)
           <informalexample>
             <programlisting>
 <![CDATA[
-  struct mychip *chip = (struct mychip *)card->private_data;
+  struct mychip *chip = card->private_data;
 ]]>
             </programlisting>
           </informalexample>
 
       <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>
 
           /* release the irq */
           if (chip->irq >= 0)
-                  free_irq(chip->irq, (void *)chip);
+                  free_irq(chip->irq, chip);
           /* release the i/o ports & memory */
           pci_release_regions(chip->pci);
           /* disable the PCI entry */
           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->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          SA_INTERRUPT|SA_SHIRQ, "My Chip", chip)) {
+                          IRQF_SHARED, "My Chip", chip)) {
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
                   return -EBUSY;
         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 struct <structname>mychip</structname> will have the
-        following fields: 
+        following fields:
 
         <informalexample>
           <programlisting>
           <programlisting>
 <![CDATA[
   if (request_irq(pci->irq, snd_mychip_interrupt,
-                  SA_INTERRUPT|SA_SHIRQ, "My Chip", 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>
 
           <programlisting>
 <![CDATA[
   if (chip->irq >= 0)
-          free_irq(chip->irq, (void *)chip);
+          free_irq(chip->irq, chip);
 ]]>
           </programlisting>
         </informalexample>
           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;
@@ -2836,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>
@@ -3048,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
@@ -3388,7 +3387,7 @@ struct _snd_pcm_runtime {
           .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
@@ -3449,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
@@ -4215,7 +4214,7 @@ struct _snd_pcm_runtime {
           <programlisting>
 <![CDATA[
   struct snd_rawmidi *rmidi;
-  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
+  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
                       irq, irq_flags, &rmidi);
 ]]>
           </programlisting>
@@ -4242,15 +4241,36 @@ 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
@@ -5333,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>
@@ -5394,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
@@ -5483,7 +5486,7 @@ 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
@@ -5562,7 +5565,7 @@ struct _snd_pcm_runtime {
          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_resume()</function> for each codec.</para></listitem>
+       <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