1 // SPDX-License-Identifier: GPL-2.0-or-later 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 2 /* 3 * atmel-pcm.c -- ALSA PCM interface for the 3 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC. 4 * 4 * 5 * Copyright (C) 2005 SAN People 5 * Copyright (C) 2005 SAN People 6 * Copyright (C) 2008 Atmel 6 * Copyright (C) 2008 Atmel 7 * 7 * 8 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel 8 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com> 9 * 9 * 10 * Based on at91-pcm. by: 10 * Based on at91-pcm. by: 11 * Frank Mandarino <fmandarino@endrelia.com> 11 * Frank Mandarino <fmandarino@endrelia.com> 12 * Copyright 2006 Endrelia Technologies Inc. 12 * Copyright 2006 Endrelia Technologies Inc. 13 * 13 * 14 * Based on pxa2xx-pcm.c by: 14 * Based on pxa2xx-pcm.c by: 15 * 15 * 16 * Author: Nicolas Pitre 16 * Author: Nicolas Pitre 17 * Created: Nov 30, 2004 17 * Created: Nov 30, 2004 18 * Copyright: (C) 2004 MontaVista Software, 18 * Copyright: (C) 2004 MontaVista Software, Inc. 19 */ 19 */ 20 20 21 #include <linux/module.h> 21 #include <linux/module.h> 22 #include <linux/init.h> 22 #include <linux/init.h> 23 #include <linux/platform_device.h> 23 #include <linux/platform_device.h> 24 #include <linux/slab.h> 24 #include <linux/slab.h> 25 #include <linux/dma-mapping.h> 25 #include <linux/dma-mapping.h> 26 #include <linux/atmel_pdc.h> 26 #include <linux/atmel_pdc.h> 27 #include <linux/atmel-ssc.h> 27 #include <linux/atmel-ssc.h> 28 28 29 #include <sound/core.h> 29 #include <sound/core.h> 30 #include <sound/pcm.h> 30 #include <sound/pcm.h> 31 #include <sound/pcm_params.h> 31 #include <sound/pcm_params.h> 32 #include <sound/soc.h> 32 #include <sound/soc.h> 33 33 34 #include "atmel-pcm.h" 34 #include "atmel-pcm.h" 35 35 36 36 37 static int atmel_pcm_new(struct snd_soc_compon !! 37 static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, 38 struct snd_soc_pcm_ru !! 38 int stream) >> 39 { >> 40 struct snd_pcm_substream *substream = pcm->streams[stream].substream; >> 41 struct snd_dma_buffer *buf = &substream->dma_buffer; >> 42 size_t size = ATMEL_SSC_DMABUF_SIZE; >> 43 >> 44 buf->dev.type = SNDRV_DMA_TYPE_DEV; >> 45 buf->dev.dev = pcm->card->dev; >> 46 buf->private_data = NULL; >> 47 buf->area = dma_alloc_coherent(pcm->card->dev, size, >> 48 &buf->addr, GFP_KERNEL); >> 49 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n", >> 50 (void *)buf->area, (void *)(long)buf->addr, size); >> 51 >> 52 if (!buf->area) >> 53 return -ENOMEM; >> 54 >> 55 buf->bytes = size; >> 56 return 0; >> 57 } >> 58 >> 59 static int atmel_pcm_mmap(struct snd_pcm_substream *substream, >> 60 struct vm_area_struct *vma) >> 61 { >> 62 return remap_pfn_range(vma, vma->vm_start, >> 63 substream->dma_buffer.addr >> PAGE_SHIFT, >> 64 vma->vm_end - vma->vm_start, vma->vm_page_prot); >> 65 } >> 66 >> 67 static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) 39 { 68 { 40 struct snd_card *card = rtd->card->snd 69 struct snd_card *card = rtd->card->snd_card; >> 70 struct snd_pcm *pcm = rtd->pcm; 41 int ret; 71 int ret; 42 72 43 ret = dma_coerce_mask_and_coherent(car 73 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); 44 if (ret) 74 if (ret) 45 return ret; 75 return ret; 46 76 47 snd_pcm_set_managed_buffer_all(rtd->pc !! 77 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 48 card->d !! 78 pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); 49 ATMEL_S !! 79 ret = atmel_pcm_preallocate_dma_buffer(pcm, >> 80 SNDRV_PCM_STREAM_PLAYBACK); >> 81 if (ret) >> 82 goto out; >> 83 } 50 84 51 return 0; !! 85 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { >> 86 pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); >> 87 ret = atmel_pcm_preallocate_dma_buffer(pcm, >> 88 SNDRV_PCM_STREAM_CAPTURE); >> 89 if (ret) >> 90 goto out; >> 91 } >> 92 out: >> 93 return ret; >> 94 } >> 95 >> 96 static void atmel_pcm_free(struct snd_pcm *pcm) >> 97 { >> 98 struct snd_pcm_substream *substream; >> 99 struct snd_dma_buffer *buf; >> 100 int stream; >> 101 >> 102 for (stream = 0; stream < 2; stream++) { >> 103 substream = pcm->streams[stream].substream; >> 104 if (!substream) >> 105 continue; >> 106 >> 107 buf = &substream->dma_buffer; >> 108 if (!buf->area) >> 109 continue; >> 110 dma_free_coherent(pcm->card->dev, buf->bytes, >> 111 buf->area, buf->addr); >> 112 buf->area = NULL; >> 113 } 52 } 114 } 53 115 54 /*-------------------------------------------- 116 /*--------------------------------------------------------------------------*\ 55 * Hardware definition 117 * Hardware definition 56 \*-------------------------------------------- 118 \*--------------------------------------------------------------------------*/ 57 /* TODO: These values were taken from the AT91 119 /* TODO: These values were taken from the AT91 platform driver, check 58 * them against real values for AT32 120 * them against real values for AT32 59 */ 121 */ 60 static const struct snd_pcm_hardware atmel_pcm 122 static const struct snd_pcm_hardware atmel_pcm_hardware = { 61 .info = SNDRV_PCM_IN 123 .info = SNDRV_PCM_INFO_MMAP | 62 SNDRV_PCM_IN 124 SNDRV_PCM_INFO_MMAP_VALID | 63 SNDRV_PCM_IN 125 SNDRV_PCM_INFO_INTERLEAVED | 64 SNDRV_PCM_IN 126 SNDRV_PCM_INFO_PAUSE, 65 .period_bytes_min = 32, 127 .period_bytes_min = 32, 66 .period_bytes_max = 8192, 128 .period_bytes_max = 8192, 67 .periods_min = 2, 129 .periods_min = 2, 68 .periods_max = 1024, 130 .periods_max = 1024, 69 .buffer_bytes_max = ATMEL_SSC_DM 131 .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, 70 }; 132 }; 71 133 72 134 73 /*-------------------------------------------- 135 /*--------------------------------------------------------------------------*\ 74 * Data types 136 * Data types 75 \*-------------------------------------------- 137 \*--------------------------------------------------------------------------*/ 76 struct atmel_runtime_data { 138 struct atmel_runtime_data { 77 struct atmel_pcm_dma_params *params; 139 struct atmel_pcm_dma_params *params; 78 dma_addr_t dma_buffer; /* phy 140 dma_addr_t dma_buffer; /* physical address of dma buffer */ 79 dma_addr_t dma_buffer_end; /* fir 141 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ 80 size_t period_size; 142 size_t period_size; 81 143 82 dma_addr_t period_ptr; /* phy 144 dma_addr_t period_ptr; /* physical address of next period */ 83 }; 145 }; 84 146 85 /*-------------------------------------------- 147 /*--------------------------------------------------------------------------*\ 86 * ISR 148 * ISR 87 \*-------------------------------------------- 149 \*--------------------------------------------------------------------------*/ 88 static void atmel_pcm_dma_irq(u32 ssc_sr, 150 static void atmel_pcm_dma_irq(u32 ssc_sr, 89 struct snd_pcm_substream *substream) 151 struct snd_pcm_substream *substream) 90 { 152 { 91 struct atmel_runtime_data *prtd = subs 153 struct atmel_runtime_data *prtd = substream->runtime->private_data; 92 struct atmel_pcm_dma_params *params = 154 struct atmel_pcm_dma_params *params = prtd->params; 93 static int count; 155 static int count; 94 156 95 count++; 157 count++; 96 158 97 if (ssc_sr & params->mask->ssc_endbuf) 159 if (ssc_sr & params->mask->ssc_endbuf) { 98 pr_warn("atmel-pcm: buffer %s 160 pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n", 99 substream->str 161 substream->stream == SNDRV_PCM_STREAM_PLAYBACK 100 ? "underrun" : 162 ? "underrun" : "overrun", 101 params->name, 163 params->name, ssc_sr, count); 102 164 103 /* re-start the PDC */ 165 /* re-start the PDC */ 104 ssc_writex(params->ssc->regs, 166 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, 105 params->mask->pdc_d 167 params->mask->pdc_disable); 106 prtd->period_ptr += prtd->peri 168 prtd->period_ptr += prtd->period_size; 107 if (prtd->period_ptr >= prtd-> 169 if (prtd->period_ptr >= prtd->dma_buffer_end) 108 prtd->period_ptr = prt 170 prtd->period_ptr = prtd->dma_buffer; 109 171 110 ssc_writex(params->ssc->regs, 172 ssc_writex(params->ssc->regs, params->pdc->xpr, 111 prtd->period_ptr); 173 prtd->period_ptr); 112 ssc_writex(params->ssc->regs, 174 ssc_writex(params->ssc->regs, params->pdc->xcr, 113 prtd->period_size / 175 prtd->period_size / params->pdc_xfer_size); 114 ssc_writex(params->ssc->regs, 176 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, 115 params->mask->pdc_e 177 params->mask->pdc_enable); 116 } 178 } 117 179 118 if (ssc_sr & params->mask->ssc_endx) { 180 if (ssc_sr & params->mask->ssc_endx) { 119 /* Load the PDC next pointer a 181 /* Load the PDC next pointer and counter registers */ 120 prtd->period_ptr += prtd->peri 182 prtd->period_ptr += prtd->period_size; 121 if (prtd->period_ptr >= prtd-> 183 if (prtd->period_ptr >= prtd->dma_buffer_end) 122 prtd->period_ptr = prt 184 prtd->period_ptr = prtd->dma_buffer; 123 185 124 ssc_writex(params->ssc->regs, 186 ssc_writex(params->ssc->regs, params->pdc->xnpr, 125 prtd->period_ptr); 187 prtd->period_ptr); 126 ssc_writex(params->ssc->regs, 188 ssc_writex(params->ssc->regs, params->pdc->xncr, 127 prtd->period_size / 189 prtd->period_size / params->pdc_xfer_size); 128 } 190 } 129 191 130 snd_pcm_period_elapsed(substream); 192 snd_pcm_period_elapsed(substream); 131 } 193 } 132 194 133 195 134 /*-------------------------------------------- 196 /*--------------------------------------------------------------------------*\ 135 * PCM operations 197 * PCM operations 136 \*-------------------------------------------- 198 \*--------------------------------------------------------------------------*/ 137 static int atmel_pcm_hw_params(struct snd_soc_ !! 199 static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, 138 struct snd_pcm_ !! 200 struct snd_pcm_hw_params *params) 139 struct snd_pcm_ << 140 { 201 { 141 struct snd_pcm_runtime *runtime = subs 202 struct snd_pcm_runtime *runtime = substream->runtime; 142 struct atmel_runtime_data *prtd = runt 203 struct atmel_runtime_data *prtd = runtime->private_data; 143 struct snd_soc_pcm_runtime *rtd = snd_ !! 204 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 205 145 /* this may get called several times b 206 /* this may get called several times by oss emulation 146 * with different params */ 207 * with different params */ 147 208 148 prtd->params = snd_soc_dai_get_dma_dat !! 209 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); >> 210 runtime->dma_bytes = params_buffer_bytes(params); >> 211 >> 212 prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 149 prtd->params->dma_intr_handler = atmel 213 prtd->params->dma_intr_handler = atmel_pcm_dma_irq; 150 214 151 prtd->dma_buffer = runtime->dma_addr; 215 prtd->dma_buffer = runtime->dma_addr; 152 prtd->dma_buffer_end = runtime->dma_ad 216 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; 153 prtd->period_size = params_period_byte 217 prtd->period_size = params_period_bytes(params); 154 218 155 pr_debug("atmel-pcm: " 219 pr_debug("atmel-pcm: " 156 "hw_params: DMA for %s initial 220 "hw_params: DMA for %s initialized " 157 "(dma_bytes=%zu, period_size=% 221 "(dma_bytes=%zu, period_size=%zu)\n", 158 prtd->params->name, 222 prtd->params->name, 159 runtime->dma_bytes, 223 runtime->dma_bytes, 160 prtd->period_size); 224 prtd->period_size); 161 return 0; 225 return 0; 162 } 226 } 163 227 164 static int atmel_pcm_hw_free(struct snd_soc_co !! 228 static int atmel_pcm_hw_free(struct snd_pcm_substream *substream) 165 struct snd_pcm_su << 166 { 229 { 167 struct atmel_runtime_data *prtd = subs 230 struct atmel_runtime_data *prtd = substream->runtime->private_data; 168 struct atmel_pcm_dma_params *params = 231 struct atmel_pcm_dma_params *params = prtd->params; 169 232 170 if (params != NULL) { 233 if (params != NULL) { 171 ssc_writex(params->ssc->regs, 234 ssc_writex(params->ssc->regs, SSC_PDC_PTCR, 172 params->mask->pdc_d 235 params->mask->pdc_disable); 173 prtd->params->dma_intr_handler 236 prtd->params->dma_intr_handler = NULL; 174 } 237 } 175 238 176 return 0; 239 return 0; 177 } 240 } 178 241 179 static int atmel_pcm_prepare(struct snd_soc_co !! 242 static int atmel_pcm_prepare(struct snd_pcm_substream *substream) 180 struct snd_pcm_su << 181 { 243 { 182 struct atmel_runtime_data *prtd = subs 244 struct atmel_runtime_data *prtd = substream->runtime->private_data; 183 struct atmel_pcm_dma_params *params = 245 struct atmel_pcm_dma_params *params = prtd->params; 184 246 185 ssc_writex(params->ssc->regs, SSC_IDR, 247 ssc_writex(params->ssc->regs, SSC_IDR, 186 params->mask->ssc_endx | pa 248 params->mask->ssc_endx | params->mask->ssc_endbuf); 187 ssc_writex(params->ssc->regs, ATMEL_PD 249 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, 188 params->mask->pdc_disable); 250 params->mask->pdc_disable); 189 return 0; 251 return 0; 190 } 252 } 191 253 192 static int atmel_pcm_trigger(struct snd_soc_co !! 254 static int atmel_pcm_trigger(struct snd_pcm_substream *substream, 193 struct snd_pcm_su !! 255 int cmd) 194 { 256 { 195 struct snd_pcm_runtime *rtd = substrea 257 struct snd_pcm_runtime *rtd = substream->runtime; 196 struct atmel_runtime_data *prtd = rtd- 258 struct atmel_runtime_data *prtd = rtd->private_data; 197 struct atmel_pcm_dma_params *params = 259 struct atmel_pcm_dma_params *params = prtd->params; 198 int ret = 0; 260 int ret = 0; 199 261 200 pr_debug("atmel-pcm:buffer_size = %ld, 262 pr_debug("atmel-pcm:buffer_size = %ld," 201 "dma_area = %p, dma_bytes = %z 263 "dma_area = %p, dma_bytes = %zu\n", 202 rtd->buffer_size, rtd->dma_are 264 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); 203 265 204 switch (cmd) { 266 switch (cmd) { 205 case SNDRV_PCM_TRIGGER_START: 267 case SNDRV_PCM_TRIGGER_START: 206 prtd->period_ptr = prtd->dma_b 268 prtd->period_ptr = prtd->dma_buffer; 207 269 208 ssc_writex(params->ssc->regs, 270 ssc_writex(params->ssc->regs, params->pdc->xpr, 209 prtd->period_ptr); 271 prtd->period_ptr); 210 ssc_writex(params->ssc->regs, 272 ssc_writex(params->ssc->regs, params->pdc->xcr, 211 prtd->period_size / 273 prtd->period_size / params->pdc_xfer_size); 212 274 213 prtd->period_ptr += prtd->peri 275 prtd->period_ptr += prtd->period_size; 214 ssc_writex(params->ssc->regs, 276 ssc_writex(params->ssc->regs, params->pdc->xnpr, 215 prtd->period_ptr); 277 prtd->period_ptr); 216 ssc_writex(params->ssc->regs, 278 ssc_writex(params->ssc->regs, params->pdc->xncr, 217 prtd->period_size / 279 prtd->period_size / params->pdc_xfer_size); 218 280 219 pr_debug("atmel-pcm: trigger: 281 pr_debug("atmel-pcm: trigger: " 220 "period_ptr=%lx, xpr=% 282 "period_ptr=%lx, xpr=%u, " 221 "xcr=%u, xnpr=%u, xncr 283 "xcr=%u, xnpr=%u, xncr=%u\n", 222 (unsigned long)prtd->p 284 (unsigned long)prtd->period_ptr, 223 ssc_readx(params->ssc- 285 ssc_readx(params->ssc->regs, params->pdc->xpr), 224 ssc_readx(params->ssc- 286 ssc_readx(params->ssc->regs, params->pdc->xcr), 225 ssc_readx(params->ssc- 287 ssc_readx(params->ssc->regs, params->pdc->xnpr), 226 ssc_readx(params->ssc- 288 ssc_readx(params->ssc->regs, params->pdc->xncr)); 227 289 228 ssc_writex(params->ssc->regs, 290 ssc_writex(params->ssc->regs, SSC_IER, 229 params->mask->ssc_e 291 params->mask->ssc_endx | params->mask->ssc_endbuf); 230 ssc_writex(params->ssc->regs, 292 ssc_writex(params->ssc->regs, SSC_PDC_PTCR, 231 params->mask->pdc_e 293 params->mask->pdc_enable); 232 294 233 pr_debug("sr=%u imr=%u\n", 295 pr_debug("sr=%u imr=%u\n", 234 ssc_readx(params->ssc- 296 ssc_readx(params->ssc->regs, SSC_SR), 235 ssc_readx(params->ssc- 297 ssc_readx(params->ssc->regs, SSC_IER)); 236 break; /* SNDRV_PCM_T 298 break; /* SNDRV_PCM_TRIGGER_START */ 237 299 238 case SNDRV_PCM_TRIGGER_STOP: 300 case SNDRV_PCM_TRIGGER_STOP: 239 case SNDRV_PCM_TRIGGER_SUSPEND: 301 case SNDRV_PCM_TRIGGER_SUSPEND: 240 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 302 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 241 ssc_writex(params->ssc->regs, 303 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, 242 params->mask->pdc_d 304 params->mask->pdc_disable); 243 break; 305 break; 244 306 245 case SNDRV_PCM_TRIGGER_RESUME: 307 case SNDRV_PCM_TRIGGER_RESUME: 246 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 308 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 247 ssc_writex(params->ssc->regs, 309 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, 248 params->mask->pdc_e 310 params->mask->pdc_enable); 249 break; 311 break; 250 312 251 default: 313 default: 252 ret = -EINVAL; 314 ret = -EINVAL; 253 } 315 } 254 316 255 return ret; 317 return ret; 256 } 318 } 257 319 258 static snd_pcm_uframes_t atmel_pcm_pointer(str !! 320 static snd_pcm_uframes_t atmel_pcm_pointer( 259 str !! 321 struct snd_pcm_substream *substream) 260 { 322 { 261 struct snd_pcm_runtime *runtime = subs 323 struct snd_pcm_runtime *runtime = substream->runtime; 262 struct atmel_runtime_data *prtd = runt 324 struct atmel_runtime_data *prtd = runtime->private_data; 263 struct atmel_pcm_dma_params *params = 325 struct atmel_pcm_dma_params *params = prtd->params; 264 dma_addr_t ptr; 326 dma_addr_t ptr; 265 snd_pcm_uframes_t x; 327 snd_pcm_uframes_t x; 266 328 267 ptr = (dma_addr_t) ssc_readx(params->s 329 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr); 268 x = bytes_to_frames(runtime, ptr - prt 330 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); 269 331 270 if (x == runtime->buffer_size) 332 if (x == runtime->buffer_size) 271 x = 0; 333 x = 0; 272 334 273 return x; 335 return x; 274 } 336 } 275 337 276 static int atmel_pcm_open(struct snd_soc_compo !! 338 static int atmel_pcm_open(struct snd_pcm_substream *substream) 277 struct snd_pcm_subst << 278 { 339 { 279 struct snd_pcm_runtime *runtime = subs 340 struct snd_pcm_runtime *runtime = substream->runtime; 280 struct atmel_runtime_data *prtd; 341 struct atmel_runtime_data *prtd; 281 int ret = 0; 342 int ret = 0; 282 343 283 snd_soc_set_runtime_hwparams(substream 344 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware); 284 345 285 /* ensure that buffer size is a multip 346 /* ensure that buffer size is a multiple of period size */ 286 ret = snd_pcm_hw_constraint_integer(ru 347 ret = snd_pcm_hw_constraint_integer(runtime, 287 348 SNDRV_PCM_HW_PARAM_PERIODS); 288 if (ret < 0) 349 if (ret < 0) 289 goto out; 350 goto out; 290 351 291 prtd = kzalloc(sizeof(struct atmel_run 352 prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); 292 if (prtd == NULL) { 353 if (prtd == NULL) { 293 ret = -ENOMEM; 354 ret = -ENOMEM; 294 goto out; 355 goto out; 295 } 356 } 296 runtime->private_data = prtd; 357 runtime->private_data = prtd; 297 358 298 out: 359 out: 299 return ret; 360 return ret; 300 } 361 } 301 362 302 static int atmel_pcm_close(struct snd_soc_comp !! 363 static int atmel_pcm_close(struct snd_pcm_substream *substream) 303 struct snd_pcm_subs << 304 { 364 { 305 struct atmel_runtime_data *prtd = subs 365 struct atmel_runtime_data *prtd = substream->runtime->private_data; 306 366 307 kfree(prtd); 367 kfree(prtd); 308 return 0; 368 return 0; 309 } 369 } 310 370 311 static const struct snd_soc_component_driver a !! 371 static const struct snd_pcm_ops atmel_pcm_ops = { 312 .open = atmel_pcm_open, 372 .open = atmel_pcm_open, 313 .close = atmel_pcm_close, 373 .close = atmel_pcm_close, >> 374 .ioctl = snd_pcm_lib_ioctl, 314 .hw_params = atmel_pcm_hw_params, 375 .hw_params = atmel_pcm_hw_params, 315 .hw_free = atmel_pcm_hw_free, 376 .hw_free = atmel_pcm_hw_free, 316 .prepare = atmel_pcm_prepare, 377 .prepare = atmel_pcm_prepare, 317 .trigger = atmel_pcm_trigger, 378 .trigger = atmel_pcm_trigger, 318 .pointer = atmel_pcm_pointer, 379 .pointer = atmel_pcm_pointer, 319 .pcm_construct = atmel_pcm_new, !! 380 .mmap = atmel_pcm_mmap, >> 381 }; >> 382 >> 383 static struct snd_soc_component_driver atmel_soc_platform = { >> 384 .ops = &atmel_pcm_ops, >> 385 .pcm_new = atmel_pcm_new, >> 386 .pcm_free = atmel_pcm_free, 320 }; 387 }; 321 388 322 int atmel_pcm_pdc_platform_register(struct dev 389 int atmel_pcm_pdc_platform_register(struct device *dev) 323 { 390 { 324 return devm_snd_soc_register_component 391 return devm_snd_soc_register_component(dev, &atmel_soc_platform, 325 392 NULL, 0); 326 } 393 } 327 EXPORT_SYMBOL(atmel_pcm_pdc_platform_register) 394 EXPORT_SYMBOL(atmel_pcm_pdc_platform_register); >> 395 >> 396 void atmel_pcm_pdc_platform_unregister(struct device *dev) >> 397 { >> 398 } >> 399 EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister); 328 400 329 MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@at 401 MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); 330 MODULE_DESCRIPTION("Atmel PCM module"); 402 MODULE_DESCRIPTION("Atmel PCM module"); 331 MODULE_LICENSE("GPL"); 403 MODULE_LICENSE("GPL"); 332 404
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.