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 5. PCM Interface"><link rel="prev" href="pcm-interface.html" title="Chapter 5. 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> </td><th width="60%" align="center">Chapter 5. PCM Interface</th><td width="20%" align="right"> <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 5.1. PCM Example Code</b></p><div class="example-contents"><pre class="programlisting"> 7 8 #include <sound/pcm.h> 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->runtime; 54 55 runtime->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->runtime; 76 77 runtime->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->runtime; 112 113 /* set up the hardware with the current configuration 114 * for example... 115 */ 116 mychip_set_sample_format(chip, runtime->format); 117 mychip_set_sample_rate(chip, runtime->rate); 118 mychip_set_channels(chip, runtime->channels); 119 mychip_set_dma_setup(chip, runtime->dma_addr, 120 chip->buffer_size, 121 chip->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->card, "My Chip", 0, 1, 1, &pcm); 190 if (err < 0) 191 return err; 192 pcm->private_data = chip; 193 strcpy(pcm->name, "My Chip"); 194 chip->pcm = pcm; 195 /* set operators */ 196 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 197 &snd_mychip_playback_ops); 198 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 199 &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->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> </td><td width="20%" align="center"><a accesskey="u" href="pcm-interface.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pcm-interface-constructor.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 5. PCM Interface </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Constructor</td></tr></table></div></body></html> 210