File: coding-1.html

package info (click to toggle)
alsadriver 0.2.0-pre8-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 2,808 kB
  • ctags: 6,550
  • sloc: ansic: 43,490; sh: 916; makefile: 759; perl: 54
file content (216 lines) | stat: -rw-r--r-- 7,054 bytes parent folder | download
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 -&gt; private_data
snd_card_t -&gt; private_free (called from snd_card_free if not NULL)
</PRE>
<HR>
</P>
<P>
<HR>
<PRE>
struct snd_stru_pcm_hardware -&gt; private_data
struct snd_stru_pcm_hardware -&gt; private_free (called from snd_pcm_free if not NULL)
snd_pcm_t -&gt; private_data
snd_pcm_t -&gt; private_free (called from snd_pcm_free if not NULL)
</PRE>
<HR>
</P>
<P>
<HR>
<PRE>
struct snd_stru_mixer_channel_hw -&gt; private_value
snd_kmixer_channel_t -&gt; private_data
snd_kmixer_channel_t -&gt; private_free (called from snd_mixer_free if not NULL)
snd_kmixer_t -&gt; private_value
snd_kmixer_t -&gt; private_data
snd_kmixer_t -&gt; 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>