<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Chip-Specific Data</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="Writing an ALSA Driver" /><link rel="up" href="ch03.html" title="Chapter 3. Management of Cards and Components" /><link rel="prev" href="ch03s02.html" title="Components" /><link rel="next" href="ch03s04.html" title="Registration and Release" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chip-Specific Data</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s02.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Management of Cards and Components</th><td width="20%" align="right"> <a accesskey="n" href="ch03s04.html">Next</a></td></tr></table><hr /></div><div class="section" title="Chip-Specific Data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="card-management-chip-specific"></a>Chip-Specific Data</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ch03s03.html#card-management-chip-specific-snd-card-new">1. Allocating via <code class="function">snd_card_create()</code>.</a></span></dt><dt><span class="section"><a href="ch03s03.html#card-management-chip-specific-allocate-extra">2. Allocating an extra device.</a></span></dt></dl></div><p> Chip-specific information, e.g. the I/O port address, its resource pointer, or the irq number, is stored in the chip-specific record. </p><div class="informalexample"><pre class="programlisting"> struct mychip { .... }; </pre></div><p> </p><p> In general, there are two ways of allocating the chip record. </p><div class="section" title="1. Allocating via snd_card_create()."><div class="titlepage"><div><div><h3 class="title"><a id="card-management-chip-specific-snd-card-new"></a>1. Allocating via <code class="function">snd_card_create()</code>.</h3></div></div></div><p> As mentioned above, you can pass the extra-data-length to the 4th argument of <code class="function">snd_card_create()</code>, i.e. </p><div class="informalexample"><pre class="programlisting"> err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip), &card); </pre></div><p> struct <span class="structname">mychip</span> is the type of the chip record. </p><p> In return, the allocated record can be accessed as </p><div class="informalexample"><pre class="programlisting"> struct mychip *chip = card->private_data; </pre></div><p> With this method, you don't have to allocate twice. The record is released together with the card instance. </p></div><div class="section" title="2. Allocating an extra device."><div class="titlepage"><div><div><h3 class="title"><a id="card-management-chip-specific-allocate-extra"></a>2. Allocating an extra device.</h3></div></div></div><p> After allocating a card instance via <code class="function">snd_card_create()</code> (with <code class="constant">0</code> on the 4th arg), call <code class="function">kzalloc()</code>. </p><div class="informalexample"><pre class="programlisting"> struct snd_card *card; struct mychip *chip; err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); ..... chip = kzalloc(sizeof(*chip), GFP_KERNEL); </pre></div><p> </p><p> The chip record should have the field to hold the card pointer at least, </p><div class="informalexample"><pre class="programlisting"> struct mychip { struct snd_card *card; .... }; </pre></div><p> </p><p> Then, set the card pointer in the returned chip instance. </p><div class="informalexample"><pre class="programlisting"> chip->card = card; </pre></div><p> </p><p> Next, initialize the fields, and register this chip record as a low-level device with a specified <em class="parameter"><code>ops</code></em>, </p><div class="informalexample"><pre class="programlisting"> static struct snd_device_ops ops = { .dev_free = snd_mychip_dev_free, }; .... snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); </pre></div><p> <code class="function">snd_mychip_dev_free()</code> is the device-destructor function, which will call the real destructor. </p><p> </p><div class="informalexample"><pre class="programlisting"> static int snd_mychip_dev_free(struct snd_device *device) { return snd_mychip_free(device->device_data); } </pre></div><p> where <code class="function">snd_mychip_free()</code> is the real destructor. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch03s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Components </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Registration and Release</td></tr></table></div></body></html>