1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Full Code Example</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Writing an ALSA Driver"><link rel="up" href="pcm-interface.html" title="Chapter&#160;5.&#160;PCM Interface"><link rel="prev" href="pcm-interface.html" title="Chapter&#160;5.&#160;PCM Interface"><link rel="next" href="pcm-interface-constructor.html" title="Constructor"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Full Code Example</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="pcm-interface.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;5.&#160;PCM Interface</th><td width="20%" align="right">&#160;<a accesskey="n" href="pcm-interface-constructor.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pcm-interface-example"></a>Full Code Example</h2></div></div></div><p>
2      The example code below does not include any hardware access
3      routines but shows only the skeleton, how to build up the PCM
4      interfaces.
5
6        </p><div class="example"><a name="idp1094006196"></a><p class="title"><b>Example&#160;5.1.&#160;PCM Example Code</b></p><div class="example-contents"><pre class="programlisting">
7
8  #include &lt;sound/pcm.h&gt;
9  ....
10
11  /* hardware definition */
12  static struct snd_pcm_hardware snd_mychip_playback_hw = {
13          .info = (SNDRV_PCM_INFO_MMAP |
14                   SNDRV_PCM_INFO_INTERLEAVED |
15                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
16                   SNDRV_PCM_INFO_MMAP_VALID),
17          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
18          .rates =            SNDRV_PCM_RATE_8000_48000,
19          .rate_min =         8000,
20          .rate_max =         48000,
21          .channels_min =     2,
22          .channels_max =     2,
23          .buffer_bytes_max = 32768,
24          .period_bytes_min = 4096,
25          .period_bytes_max = 32768,
26          .periods_min =      1,
27          .periods_max =      1024,
28  };
29
30  /* hardware definition */
31  static struct snd_pcm_hardware snd_mychip_capture_hw = {
32          .info = (SNDRV_PCM_INFO_MMAP |
33                   SNDRV_PCM_INFO_INTERLEAVED |
34                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
35                   SNDRV_PCM_INFO_MMAP_VALID),
36          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
37          .rates =            SNDRV_PCM_RATE_8000_48000,
38          .rate_min =         8000,
39          .rate_max =         48000,
40          .channels_min =     2,
41          .channels_max =     2,
42          .buffer_bytes_max = 32768,
43          .period_bytes_min = 4096,
44          .period_bytes_max = 32768,
45          .periods_min =      1,
46          .periods_max =      1024,
47  };
48
49  /* open callback */
50  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
51  {
52          struct mychip *chip = snd_pcm_substream_chip(substream);
53          struct snd_pcm_runtime *runtime = substream-&gt;runtime;
54
55          runtime-&gt;hw = snd_mychip_playback_hw;
56          /* more hardware-initialization will be done here */
57          ....
58          return 0;
59  }
60
61  /* close callback */
62  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
63  {
64          struct mychip *chip = snd_pcm_substream_chip(substream);
65          /* the hardware-specific codes will be here */
66          ....
67          return 0;
68
69  }
70
71  /* open callback */
72  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
73  {
74          struct mychip *chip = snd_pcm_substream_chip(substream);
75          struct snd_pcm_runtime *runtime = substream-&gt;runtime;
76
77          runtime-&gt;hw = snd_mychip_capture_hw;
78          /* more hardware-initialization will be done here */
79          ....
80          return 0;
81  }
82
83  /* close callback */
84  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
85  {
86          struct mychip *chip = snd_pcm_substream_chip(substream);
87          /* the hardware-specific codes will be here */
88          ....
89          return 0;
90
91  }
92
93  /* hw_params callback */
94  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
95                               struct snd_pcm_hw_params *hw_params)
96  {
97          return snd_pcm_lib_malloc_pages(substream,
98                                     params_buffer_bytes(hw_params));
99  }
100
101  /* hw_free callback */
102  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
103  {
104          return snd_pcm_lib_free_pages(substream);
105  }
106
107  /* prepare callback */
108  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
109  {
110          struct mychip *chip = snd_pcm_substream_chip(substream);
111          struct snd_pcm_runtime *runtime = substream-&gt;runtime;
112
113          /* set up the hardware with the current configuration
114           * for example...
115           */
116          mychip_set_sample_format(chip, runtime-&gt;format);
117          mychip_set_sample_rate(chip, runtime-&gt;rate);
118          mychip_set_channels(chip, runtime-&gt;channels);
119          mychip_set_dma_setup(chip, runtime-&gt;dma_addr,
120                               chip-&gt;buffer_size,
121                               chip-&gt;period_size);
122          return 0;
123  }
124
125  /* trigger callback */
126  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
127                                    int cmd)
128  {
129          switch (cmd) {
130          case SNDRV_PCM_TRIGGER_START:
131                  /* do something to start the PCM engine */
132                  ....
133                  break;
134          case SNDRV_PCM_TRIGGER_STOP:
135                  /* do something to stop the PCM engine */
136                  ....
137                  break;
138          default:
139                  return -EINVAL;
140          }
141  }
142
143  /* pointer callback */
144  static snd_pcm_uframes_t
145  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
146  {
147          struct mychip *chip = snd_pcm_substream_chip(substream);
148          unsigned int current_ptr;
149
150          /* get the current hardware pointer */
151          current_ptr = mychip_get_hw_pointer(chip);
152          return current_ptr;
153  }
154
155  /* operators */
156  static struct snd_pcm_ops snd_mychip_playback_ops = {
157          .open =        snd_mychip_playback_open,
158          .close =       snd_mychip_playback_close,
159          .ioctl =       snd_pcm_lib_ioctl,
160          .hw_params =   snd_mychip_pcm_hw_params,
161          .hw_free =     snd_mychip_pcm_hw_free,
162          .prepare =     snd_mychip_pcm_prepare,
163          .trigger =     snd_mychip_pcm_trigger,
164          .pointer =     snd_mychip_pcm_pointer,
165  };
166
167  /* operators */
168  static struct snd_pcm_ops snd_mychip_capture_ops = {
169          .open =        snd_mychip_capture_open,
170          .close =       snd_mychip_capture_close,
171          .ioctl =       snd_pcm_lib_ioctl,
172          .hw_params =   snd_mychip_pcm_hw_params,
173          .hw_free =     snd_mychip_pcm_hw_free,
174          .prepare =     snd_mychip_pcm_prepare,
175          .trigger =     snd_mychip_pcm_trigger,
176          .pointer =     snd_mychip_pcm_pointer,
177  };
178
179  /*
180   *  definitions of capture are omitted here...
181   */
182
183  /* create a pcm device */
184  static int snd_mychip_new_pcm(struct mychip *chip)
185  {
186          struct snd_pcm *pcm;
187          int err;
188
189          err = snd_pcm_new(chip-&gt;card, "My Chip", 0, 1, 1, &amp;pcm);
190          if (err &lt; 0) 
191                  return err;
192          pcm-&gt;private_data = chip;
193          strcpy(pcm-&gt;name, "My Chip");
194          chip-&gt;pcm = pcm;
195          /* set operators */
196          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
197                          &amp;snd_mychip_playback_ops);
198          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
199                          &amp;snd_mychip_capture_ops);
200          /* pre-allocation of buffers */
201          /* NOTE: this may fail */
202          snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
203                                                snd_dma_pci_data(chip-&gt;pci),
204                                                64*1024, 64*1024);
205          return 0;
206  }
207
208          </pre></div></div><p><br class="example-break">
209      </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pcm-interface.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="pcm-interface.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="pcm-interface-constructor.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&#160;5.&#160;PCM Interface&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Constructor</td></tr></table></div></body></html>
210