📄 writing-an-alsa-driver.tmpl
字号:
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"><book><?dbhtml filename="index.html"><!-- ****************************************************** --><!-- Header --><!-- ****************************************************** --> <bookinfo> <title>Writing an ALSA Driver</title> <author> <firstname>Takashi</firstname> <surname>Iwai</surname> <affiliation> <address> <email>tiwai@suse.de</email> </address> </affiliation> </author> <date>July 11, 2004</date> <edition>0.3.3</edition> <abstract> <para> This document describes how to write an ALSA (Advanced Linux Sound Architecture) driver. </para> </abstract> <legalnotice> <para> Copyright (c) 2002-2004 Takashi Iwai <email>tiwai@suse.de</email> </para> <para> This document is free; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. </para> <para> This document is distributed in the hope that it will be useful, but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE</emphasis>. See the GNU General Public License for more details. </para> <para> You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA </para> </legalnotice> </bookinfo><!-- ****************************************************** --><!-- Preface --><!-- ****************************************************** --> <preface id="preface"> <title>Preface</title> <para> This document describes how to write an <ulink url="http://www.alsa-project.org/"><citetitle> ALSA (Advanced Linux Sound Architecture)</citetitle></ulink> driver. The document focuses mainly on the PCI soundcard. In the case of other device types, the API might be different, too. However, at least the ALSA kernel API is consistent, and therefore it would be still a bit help for writing them. </para> <para> The target of this document is ones who already have enough skill of C language and have the basic knowledge of linux kernel programming. This document doesn't explain the general topics of linux kernel codes and doesn't cover the detail of implementation of each low-level driver. It describes only how is the standard way to write a PCI sound driver on ALSA. </para> <para> If you are already familiar with the older ALSA ver.0.5.x, you can check the drivers such as <filename>es1938.c</filename> or <filename>maestro3.c</filename> which have also almost the same code-base in the ALSA 0.5.x tree, so you can compare the differences. </para> <para> This document is still a draft version. Any feedbacks and corrections, please!! </para> </preface><!-- ****************************************************** --><!-- File Tree Structure --><!-- ****************************************************** --> <chapter id="file-tree"> <title>File Tree Structure</title> <section id="file-tree-general"> <title>General</title> <para> The ALSA drivers are provided in the two ways. </para> <para> One is the 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 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 later environment. The latter, alsa-driver, contains many subtle files for compiling the ALSA driver on the outside of Linux kernel like configure script, the wrapper functions for older, 2.2 and 2.4 kernels, to adapt the latest kernel API, and additional drivers which are still in development or in tests. The drivers in alsa-driver tree will be moved to alsa-kernel (eventually 2.6 kernel tree) once when they are finished and confirmed to work fine. </para> <para> The file tree structure of ALSA driver is depicted below. Both alsa-kernel and alsa-driver have almost the same file structure, except for <quote>core</quote> directory. It's named as <quote>acore</quote> in alsa-driver tree. <example> <title>ALSA File Tree Structure</title> <literallayout> sound /core /oss /seq /oss /instr /ioctl32 /include /drivers /mpu401 /opl3 /i2c /l3 /synth /emux /pci /(cards) /isa /(cards) /arm /ppc /sparc /usb /pcmcia /(cards) /oss </literallayout> </example> </para> </section> <section id="file-tree-core-directory"> <title>core directory</title> <para> This directory contains the middle layer, that is, the heart of ALSA drivers. In this directory, the native ALSA modules are stored. The sub-directories contain different modules and are dependent upon the kernel config. </para> <section id="file-tree-core-directory-oss"> <title>core/oss</title> <para> The codes for PCM and mixer OSS emulation modules are stored in this directory. The rawmidi OSS emulation is included in the ALSA rawmidi code since it's quite small. The sequencer code is stored in core/seq/oss directory (see <link linkend="file-tree-core-directory-seq-oss"><citetitle> below</citetitle></link>). </para> </section> <section id="file-tree-core-directory-ioctl32"> <title>core/ioctl32</title> <para> This directory contains the 32bit-ioctl wrappers for 64bit architectures such like x86-64, ppc64 and sparc64. For 32bit and alpha architectures, these are not compiled. </para> </section> <section id="file-tree-core-directory-seq"> <title>core/seq</title> <para> This and its sub-directories are for the ALSA sequencer. This directory contains the sequencer core and primary sequencer modules such like snd-seq-midi, snd-seq-virmidi, etc. They are compiled only when <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel config. </para> </section> <section id="file-tree-core-directory-seq-oss"> <title>core/seq/oss</title> <para> This contains the OSS sequencer emulation codes. </para> </section> <section id="file-tree-core-directory-deq-instr"> <title>core/seq/instr</title> <para> This directory contains the modules for the sequencer instrument layer. </para> </section> </section> <section id="file-tree-include-directory"> <title>include directory</title> <para> This is the place for the public header files of ALSA drivers, which are to be exported to the user-space, or included by several files at different directories. Basically, the private header files should not be placed in this directory, but you may still find files there, due to historical reason :) </para> </section> <section id="file-tree-drivers-directory"> <title>drivers directory</title> <para> This directory contains the codes shared among different drivers on the different architectures. They are hence supposed not to be architecture-specific. For example, the dummy pcm driver and the serial MIDI driver are found in this directory. In the sub-directories, there are the codes for components which are independent from bus and cpu architectures. </para> <section id="file-tree-drivers-directory-mpu401"> <title>drivers/mpu401</title> <para> The MPU401 and MPU401-UART modules are stored here. </para> </section> <section id="file-tree-drivers-directory-opl3"> <title>drivers/opl3 and opl4</title> <para> The OPL3 and OPL4 FM-synth stuff is found here. </para> </section> </section> <section id="file-tree-i2c-directory"> <title>i2c directory</title> <para> This contains the ALSA i2c components. </para> <para> Although there is a standard i2c layer on Linux, ALSA has its own i2c codes for some cards, because the soundcard needs only a simple operation and the standard i2c API is too complicated for such a purpose. </para> <section id="file-tree-i2c-directory-l3"> <title>i2c/l3</title> <para> This is a sub-directory for ARM L3 i2c. </para> </section> </section> <section id="file-tree-synth-directory"> <title>synth directory</title> <para> This contains the synth middle-level modules. </para> <para> So far, there is only Emu8000/Emu10k1 synth driver under synth/emux sub-directory. </para> </section> <section id="file-tree-pci-directory"> <title>pci directory</title> <para> This and its sub-directories hold the top-level card modules for PCI soundcards and the codes specific to the PCI BUS. </para> <para> The drivers compiled from a single file is stored directly on pci directory, while the drivers with several source files are stored on its own sub-directory (e.g. emu10k1, ice1712). </para> </section> <section id="file-tree-isa-directory"> <title>isa directory</title> <para> This and its sub-directories hold the top-level card modules for ISA soundcards. </para> </section> <section id="file-tree-arm-ppc-sparc-directories"> <title>arm, ppc, and sparc directories</title> <para> These are for the top-level card modules which are specific to each given architecture. </para> </section> <section id="file-tree-usb-directory"> <title>usb directory</title> <para> This contains the USB-audio driver. On the latest version, the USB MIDI driver is integrated together with usb-audio driver. </para> </section> <section id="file-tree-pcmcia-directory"> <title>pcmcia directory</title> <para> The PCMCIA, especially PCCard drivers will go here. CardBus drivers will be on pci directory, because its API is identical with the standard PCI cards. </para> </section> <section id="file-tree-oss-directory"> <title>oss directory</title> <para> The OSS/Lite source files are stored here on Linux 2.6 (or later) tree. (In the ALSA driver tarball, it's empty, of course :) </para> </section> </chapter><!-- ****************************************************** --><!-- Basic Flow for PCI Drivers --><!-- ****************************************************** --> <chapter id="basic-flow"> <title>Basic Flow for PCI Drivers</title> <section id="basic-flow-outline"> <title>Outline</title> <para> The minimum flow of PCI soundcard is like the following: <itemizedlist> <listitem><para>define the PCI ID table (see the section <link linkend="pci-resource-entries"><citetitle>PCI Entries </citetitle></link>).</para></listitem> <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>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem> </itemizedlist> </para> </section> <section id="basic-flow-example"> <title>Full Code Example</title> <para> The code example is shown below. Some parts are kept unimplemented at this moment but will be filled in the succeeding sections. The numbers in comment lines of <function>snd_mychip_probe()</function> function are the markers. <example> <title>Basic Flow for PCI Drivers Example</title> <programlisting><![CDATA[ #include <sound/driver.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> /* module parameters (see "Module Parameters") */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 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; // rest of implementation will be in the section // "PCI Resource Managements" };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -