1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
<HTML>
<HEAD>
<TITLE>Advanced Linux Sound Architecture - Driver: Introduction</TITLE>
</HEAD>
<BODY>
Previous
<A HREF="coding-2.html">Next</A>
<A HREF="coding.html#toc1">Table of Contents</A>
<HR>
<H2><A NAME="s1">1. Introduction</A></H2>
<P>This document describes the ALSA driver and kernel API. Application
programmers should use the library API rather than kernel API.
The ALSA Library offers 100% of the functionally of the kernel API, but add
next major improvements in usability, making the application code simpler and
better looking. In addition, some of the some fixes/compatibility code in,
may be placed in the library code instead of the kernel driver.</P>
<H2><A NAME="ss1.1">1.1 Source files</A></H2>
<P>Source files are separated to:</P>
<P>
<DL>
<DT><B>/include</B><DD><P>Directory contains all header files which are included from more sources.</P>
<DT><B>/kernel</B><DD><P>Directory with kernel code and abstract layers (middle level code and library).</P>
<DT><B>/lowlevel</B><DD><P>Generic lowlevel code for chip(set)s.</P>
<DT><B>/cards</B><DD><P>Upper level for soundcards and specific lowlevel code.</P>
<DT><B>/detect</B><DD><P>Detection layer (<I>/proc/asound/detect</I> - to make installation easy).</P>
</DL>
</P>
<H2><A NAME="ss1.2">1.2 Devices</A></H2>
<P>Devices should use abstract code from sound kernel, but it should use
own code and register minors separetely (with snd_minor_register and
snd_minor_unregister functions). This method totaly bypass all abstract
code, so code for these soundcards must handle all things.</P>
<H2><A NAME="ss1.3">1.3 Memory allocation</A></H2>
<P>
<UL>
<LI><B>void *snd_malloc( unsigned long size )</B></LI>
<LI><B>void snd_free( void *ptr, unsigned long size )</B></LI>
<LI><B>char *snd_malloc_strdup( char *string )</B></LI>
<LI><B>void snd_free_str( char *string )</B></LI>
</UL>
</P>
<P>Routines uses it's own memory allocation algoritm. It should be removed
in future and replaced with kmalloc and kfree calls, but I need trace
all allocation problems to make code clean...</P>
<P>Note: ALSA driver heavy uses dynamic allocation for most things.</P>
<P>For debugging you should use command './configure --with-debug=full' for
configuration. This enables trace of allocated memory with above functions
and this makes debugging a little bit easier.</P>
<H2><A NAME="ss1.4">1.4 Basic coding</A></H2>
<P>All things are made as object (which encapsulates data and functions) and are
referenced in this way. I don't preferr pass index to some array of structure
or something this. Pointer to object which contains data and functions should
be passed rather (like C++).</P>
<P>All main structures should have snd_xxxx_new, snd_xxxx_free, snd_xxxx_register,
snd_xxxx_unregister functions.</P>
<P>
<UL>
<LI><B>snd_card_t</B> is basic structure which contains info about soundcard,
index and resource tracking variables. You should look to <I>include/driver.h</I>
for all things related to this structure.</LI>
</UL>
</P>
<P>
<UL>
<LI><B>snd_pcm_t</B> is basic structure for PCM device.</LI>
<LI><B>snd_pcm_channel_t</B> is basic structure for PCM channel (direction).</LI>
<LI><B>struct snd_stru_pcm_hardware</B> is structure which must be filled
by lowlevel code. You should look to <I>include/pcm.h</I> for all things
related to these structures.</LI>
</UL>
</P>
<P>
<UL>
<LI><B>snd_kmixer_t</B> is basic structure for MIXER device.</LI>
<LI><B>snd_kmixer_channel_t</B> is basic structure for MIXER channel.</LI>
<LI><B>struct snd_stru_mixer_channel_hw</B> is structure which must be filled
by lowlevel code. You should look to <I>include/mixer.h</I> for all things
related to these structures.</LI>
</UL>
</P>
<H2><A NAME="ss1.5">1.5 Upper level (/cards)</A></H2>
<P>Code for soundcards should contain these things:</P>
<P>
<OL>
<LI>Support for more same soundcards (up to SND_CARDS)...
<UL>
<LI>it isn't really possible due to HW limitations</LI>
</UL>
</LI>
<LI>Autodetection/autoconfiguration feature (if it's possible)...
<UL>
<LI>if lowlevel code is specific for soundcard type - it should be here, too..</LI>
</UL>
</LI>
<LI>Initialization code for soundcard
<UL>
<LI>snd_card_new</LI>
<LI>snd_card_free (frees all hardware resources)</LI>
</UL>
</LI>
<LI>Allocate/free hardware resources for soundcard
<UL>
<LI>snd_register_ioport</LI>
<LI>snd_unregister_ioports (frees all ioports)</LI>
<LI>snd_register_interrupt</LI>
<LI>snd_unregister_interrupts (frees all interrupts)</LI>
<LI>snd_register_dma_channel</LI>
<LI>snd_unregister_dma_channels (frees all DMA channels)</LI>
</UL>
</LI>
<LI>Initialize other layers (PCMs, Mixers etc.)
<UL>
<LI>snd_pcm_new</LI>
<LI>snd_pcm_free</LI>
<LI>snd_pcm_register</LI>
<LI>snd_pcm_unregister (calls snd_pcm_free)</LI>
<LI>snd_mixer_new</LI>
<LI>snd_mixer_free</LI>
<LI>snd_mixer_register</LI>
<LI>snd_mixer_unregister (calls snd_mixer_free)</LI>
</UL>
</LI>
<LI>Register soundcard
<UL>
<LI>snd_card_register</LI>
<LI>snd_card_unregister (doesn't calls snd_card_free)</LI>
</UL>
</LI>
</OL>
</P>
<P><B>Note:</B>
Due to module dependency you should separate code for soundcards
from same manufacture which have slightly different hardware.
Example: GUS Extreme have ESS ES-1688 chip. This chip isn't in GUS
Classic. For GUS Classic isn't generic code in snd-es1688.o module
needed, so there is two upper level modules (snd-gusextreme.o and
snd-gusclassic.o).</P>
<H2><A NAME="ss1.6">1.6 Private data/values</A></H2>
<P>Some structures have pointers on private data and values. These variables
aren't used with abstract layers and use is intended for low-level code. </P>
<P>
<HR>
<PRE>
snd_card_t -> private_data
snd_card_t -> private_free (called from snd_card_free if not NULL)
</PRE>
<HR>
</P>
<P>
<HR>
<PRE>
struct snd_stru_pcm_hardware -> private_data
struct snd_stru_pcm_hardware -> private_free (called from snd_pcm_free if not NULL)
snd_pcm_t -> private_data
snd_pcm_t -> private_free (called from snd_pcm_free if not NULL)
</PRE>
<HR>
</P>
<P>
<HR>
<PRE>
struct snd_stru_mixer_channel_hw -> private_value
snd_kmixer_channel_t -> private_data
snd_kmixer_channel_t -> private_free (called from snd_mixer_free if not NULL)
snd_kmixer_t -> private_value
snd_kmixer_t -> private_data
snd_kmixer_t -> private_free (called from snd_mixer_free if not NULL)
</PRE>
<HR>
</P>
<H2><A NAME="ss1.7">1.7 CLI/STI & spin locking</A></H2>
<P>Good code shouldn't contains <I>snd_cli()</I>/<I>snd_sti()</I> calls.
Use rather spin locks <I>snd_spin_lock()</I>/<I>snd_spin_unlock()</I>
for locking some code. This code is much better for SMP machines.</P>
<P><B>Note:</B> Debugging code is available and it should be enabled in
<I>sndspinlock.h</I>.</P>
<H2><A NAME="ss1.8">1.8 Examples</A></H2>
<P>You should look to code for GUS soundcards how can be things done...</P>
<P><B>Note:</B> Code should be compiled cleanly under 2.0.X kernels and under
latest 2.1.X kernels...</P>
<HR>
Previous
<A HREF="coding-2.html">Next</A>
<A HREF="coding.html#toc1">Table of Contents</A>
</BODY>
</HTML>
|