[ubicom32]: move new files out from platform support patch
[openwrt/svn-archive/archive.git] / target / linux / ubicom32 / files / sound / ubicom32 / ubi32-pcm.c
1 /*
2 * sound/ubicom32/ubi32-pcm.c
3 * Interface to ubicom32 virtual audio peripheral
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28
29 #include <linux/interrupt.h>
30 #include <sound/core.h>
31 #include <sound/pcm.h>
32 #include <sound/pcm_params.h>
33 #include <asm/ip5000.h>
34 #include <asm/ubi32-pcm.h>
35 #include <linux/dma-mapping.h>
36 #include <linux/delay.h>
37 #include "ubi32.h"
38
39 struct ubi32_snd_runtime_data {
40 dma_addr_t dma_buffer; /* Physical address of DMA buffer */
41 dma_addr_t dma_buffer_end; /* First address beyond end of DMA buffer */
42 size_t period_size;
43 dma_addr_t period_ptr; /* Physical address of next period */
44 unsigned int flags;
45 };
46
47 static void snd_ubi32_vp_int_set(struct snd_pcm *pcm)
48 {
49 struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
50 ubi32_priv->ar->int_req |= (1 << ubi32_priv->irq_idx);
51 ubicom32_set_interrupt(ubi32_priv->tx_irq);
52 }
53
54 static snd_pcm_uframes_t snd_ubi32_pcm_pointer(struct snd_pcm_substream *substream)
55 {
56
57 struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
58 struct audio_dev_regs *adr = ubi32_priv->adr;
59 struct snd_pcm_runtime *runtime = substream->runtime;
60 struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
61
62 dma_addr_t read_pos;
63
64 snd_pcm_uframes_t frames;
65 if (!adr->primary_os_buffer_ptr) {
66 /*
67 * If primary_os_buffer_ptr is NULL (e.g. right after the HW is started or
68 * when the HW is stopped), then handle this case separately.
69 */
70 return 0;
71 }
72
73 read_pos = (dma_addr_t)adr->primary_os_buffer_ptr;
74 frames = bytes_to_frames(runtime, read_pos - ubi32_rd->dma_buffer);
75 if (frames == runtime->buffer_size) {
76 frames = 0;
77 }
78 return frames;
79 }
80
81 /*
82 * Audio trigger
83 */
84 static int snd_ubi32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
85 {
86 struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
87 struct audio_dev_regs *adr = ubi32_priv->adr;
88 struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
89 int ret = 0;
90
91 #ifdef CONFIG_SND_DEBUG
92 snd_printk(KERN_INFO "snd_ubi32_pcm_trigger cmd=%d=", cmd);
93 #endif
94
95 if (adr->command != AUDIO_CMD_NONE) {
96 snd_printk(KERN_WARNING "Can't send command to audio device at this time\n");
97 // Set a timer to call this function back later. How to do this?
98 return 0;
99 }
100
101 /*
102 * Set interrupt flag to indicate that we interrupted audio device
103 * to send a command
104 */
105
106 switch (cmd) {
107 case SNDRV_PCM_TRIGGER_START:
108
109 #ifdef CONFIG_SND_DEBUG
110 snd_printk(KERN_INFO "START\n");
111 #endif
112 /*
113 * Ready the DMA transfer
114 */
115 ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
116
117 #ifdef CONFIG_SND_DEBUG
118 snd_printk(KERN_INFO "trigger period_ptr=%lx\n", (unsigned long)ubi32_rd->period_ptr);
119 #endif
120 adr->dma_xfer_requests[0].ptr = (void *)ubi32_rd->period_ptr;
121 adr->dma_xfer_requests[0].ctr = ubi32_rd->period_size;
122 adr->dma_xfer_requests[0].active = 1;
123
124 #ifdef CONFIG_SND_DEBUG
125 snd_printk(KERN_INFO "xfer_request 0 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
126 #endif
127
128 ubi32_rd->period_ptr += ubi32_rd->period_size;
129 adr->dma_xfer_requests[1].ptr = (void *)ubi32_rd->period_ptr;
130 adr->dma_xfer_requests[1].ctr = ubi32_rd->period_size;
131 adr->dma_xfer_requests[1].active = 1;
132
133 #ifdef CONFIG_SND_DEBUG
134 snd_printk(KERN_INFO "xfer_request 1 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
135 #endif
136
137 /*
138 * Tell the VP that we want to begin playback by filling in the
139 * command field and then interrupting the audio VP
140 */
141 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
142 adr->command = AUDIO_CMD_START;
143 snd_ubi32_vp_int_set(substream->pcm);
144 break;
145
146 case SNDRV_PCM_TRIGGER_STOP:
147
148 #ifdef CONFIG_SND_DEBUG
149 snd_printk(KERN_INFO "STOP\n");
150 #endif
151
152 /*
153 * Tell the VP that we want to stop playback by filling in the
154 * command field and then interrupting the audio VP
155 */
156 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
157 adr->command = AUDIO_CMD_STOP;
158 snd_ubi32_vp_int_set(substream->pcm);
159 break;
160
161 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
162
163 #ifdef CONFIG_SND_DEBUG
164 snd_printk(KERN_INFO "PAUSE_PUSH\n");
165 #endif
166
167 /*
168 * Tell the VP that we want to pause playback by filling in the
169 * command field and then interrupting the audio VP
170 */
171 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
172 adr->command = AUDIO_CMD_PAUSE;
173 snd_ubi32_vp_int_set(substream->pcm);
174 break;
175
176 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
177
178 #ifdef CONFIG_SND_DEBUG
179 snd_printk(KERN_INFO "PAUSE_RELEASE\n");
180 #endif
181 /*
182 * Tell the VP that we want to resume paused playback by filling
183 * in the command field and then interrupting the audio VP
184 */
185 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
186 adr->command = AUDIO_CMD_RESUME;
187 snd_ubi32_vp_int_set(substream->pcm);
188 break;
189
190 default:
191 snd_printk(KERN_WARNING "Unhandled trigger\n");
192 ret = -EINVAL;
193 break;
194 }
195
196 return ret;
197 }
198
199 /*
200 * Prepare to transfer an audio stream to the codec
201 */
202 static int snd_ubi32_pcm_prepare(struct snd_pcm_substream *substream)
203 {
204 /*
205 * Configure registers and setup the runtime instance for DMA transfers
206 */
207 struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
208 struct audio_dev_regs *adr = ubi32_priv->adr;
209
210 #ifdef CONFIG_SND_DEBUG
211 snd_printk(KERN_INFO "snd_ubi32_pcm_prepare: sending STOP command to audio device\n");
212 #endif
213
214 /*
215 * Make sure the audio device is stopped
216 */
217
218 /*
219 * Set interrupt flag to indicate that we interrupted audio device
220 * to send a command
221 */
222 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
223 adr->command = AUDIO_CMD_STOP;
224 snd_ubi32_vp_int_set(substream->pcm);
225
226 return 0;
227 }
228
229 /*
230 * Allocate DMA buffers from preallocated memory.
231 * Preallocation was done in snd_ubi32_pcm_new()
232 */
233 static int snd_ubi32_pcm_hw_params(struct snd_pcm_substream *substream,
234 struct snd_pcm_hw_params *hw_params)
235 {
236 struct snd_pcm_runtime *runtime = substream->runtime;
237 struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
238 struct audio_dev_regs *adr = ubi32_priv->adr;
239 struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
240
241 /*
242 * Use pre-allocated memory from ubi32_snd_pcm_new() to satisfy
243 * this memory request.
244 */
245 int ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
246 if (ret < 0) {
247 return ret;
248 }
249
250 #ifdef CONFIG_SND_DEBUG
251 snd_printk(KERN_INFO "snd_ubi32_pcm_hw_params\n");
252 #endif
253
254 if (!(adr->channel_mask & (1 << params_channels(hw_params)))) {
255 snd_printk(KERN_INFO "snd_ubi32_pcm_hw_params unsupported number of channels %d mask %08x\n", params_channels(hw_params), adr->channel_mask);
256 return -EINVAL;
257 }
258
259 if (ubi32_priv->set_channels) {
260 int ret = ubi32_priv->set_channels(ubi32_priv, params_channels(hw_params));
261 if (ret) {
262 snd_printk(KERN_WARNING "Unable to set channels to %d, ret=%d\n", params_channels(hw_params), ret);
263 return ret;
264 }
265 }
266
267 if (ubi32_priv->set_rate) {
268 int ret = ubi32_priv->set_rate(ubi32_priv, params_rate(hw_params));
269 if (ret) {
270 snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
271 return ret;
272 }
273 }
274
275 if (ubi32_priv->pdata->set_rate) {
276 int ret = ubi32_priv->pdata->set_rate(ubi32_priv->pdata->appdata, params_rate(hw_params));
277 if (ret) {
278 snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
279 return ret;
280 }
281 }
282
283 if (adr->command != AUDIO_CMD_NONE) {
284 snd_printk(KERN_WARNING "snd_ubi32_pcm_hw_params: tio busy\n");
285 return -EAGAIN;
286 }
287
288 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) {
289 adr->flags |= CMD_START_FLAG_LE;
290 } else {
291 adr->flags &= ~CMD_START_FLAG_LE;
292 }
293 adr->channels = params_channels(hw_params);
294 adr->sample_rate = params_rate(hw_params);
295 adr->command = AUDIO_CMD_SETUP;
296 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
297 snd_ubi32_vp_int_set(substream->pcm);
298
299 /*
300 * Wait for the command to complete
301 */
302 while (adr->command != AUDIO_CMD_NONE) {
303 udelay(1);
304 }
305
306 /*
307 * Put the DMA info into the DMA descriptor that we will
308 * use to do transfers to our audio VP "hardware"
309 */
310
311 /*
312 * Mark both DMA transfers as not ready/inactive
313 */
314 adr->dma_xfer_requests[0].active = 0;
315 adr->dma_xfer_requests[1].active = 0;
316
317 /*
318 * Put the location of the buffer into the runtime data instance
319 */
320 ubi32_rd->dma_buffer = (dma_addr_t)runtime->dma_area;
321 ubi32_rd->dma_buffer_end = (dma_addr_t)(runtime->dma_area + runtime->dma_bytes);
322
323 /*
324 * Get the period size
325 */
326 ubi32_rd->period_size = params_period_bytes(hw_params);
327
328 #ifdef CONFIG_SND_DEBUG
329 snd_printk(KERN_INFO "DMA for ubi32 audio initialized dma_area=0x%x dma_bytes=%d, period_size=%d\n", (unsigned int)runtime->dma_area, (unsigned int)runtime->dma_bytes, ubi32_rd->period_size);
330 snd_printk(KERN_INFO "Private buffer ubi32_rd: dma_buffer=0x%x dma_buffer_end=0x%x ret=%d\n", ubi32_rd->dma_buffer, ubi32_rd->dma_buffer_end, ret);
331 #endif
332
333 return ret;
334 }
335
336 /*
337 * This is the reverse of snd_ubi32_pcm_hw_params
338 */
339 static int snd_ubi32_pcm_hw_free(struct snd_pcm_substream *substream)
340 {
341 #ifdef CONFIG_SND_DEBUG
342 snd_printk(KERN_INFO "snd_ubi32_pcm_hw_free\n");
343 #endif
344 return snd_pcm_lib_free_pages(substream);
345 }
346
347 /*
348 * Audio virtual peripheral capabilities (capture and playback are identical)
349 */
350 static struct snd_pcm_hardware snd_ubi32_pcm_hw =
351 {
352 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
353 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
354 .buffer_bytes_max = (64*1024),
355 .period_bytes_min = 64,
356 .period_bytes_max = 8184,//8184,//8176,
357 .periods_min = 2,
358 .periods_max = 255,
359 .fifo_size = 0, // THIS IS IGNORED BY ALSA
360 };
361
362 /*
363 * We fill this in later
364 */
365 static struct snd_pcm_hw_constraint_list ubi32_pcm_rates;
366
367 /*
368 * snd_ubi32_pcm_close
369 */
370 static int snd_ubi32_pcm_close(struct snd_pcm_substream *substream)
371 {
372 /* Disable codec, stop DMA, free private data structures */
373 //struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
374 struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
375
376 #ifdef CONFIG_SND_DEBUG
377 snd_printk(KERN_INFO "snd_ubi32_pcm_close\n");
378 #endif
379
380 substream->runtime->private_data = NULL;
381
382 kfree(ubi32_rd);
383
384 return 0;
385 }
386
387 /*
388 * snd_ubi32_pcm_open
389 */
390 static int snd_ubi32_pcm_open(struct snd_pcm_substream *substream)
391 {
392 struct snd_pcm_runtime *runtime = substream->runtime;
393 struct ubi32_snd_runtime_data *ubi32_rd;
394 int ret = 0;
395
396 #ifdef CONFIG_SND_DEBUG
397 snd_printk(KERN_INFO "ubi32 pcm open\n");
398 #endif
399
400 /* Associate capabilities with component */
401 runtime->hw = snd_ubi32_pcm_hw;
402
403 /*
404 * Inform ALSA about constraints of the audio device
405 */
406 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &ubi32_pcm_rates);
407 if (ret < 0) {
408 snd_printk(KERN_INFO "invalid rate\n");
409 goto out;
410 }
411
412 /* Force the buffer size to be an integer multiple of period size */
413 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
414 if (ret < 0) {
415 snd_printk(KERN_INFO "invalid period\n");
416 goto out;
417 }
418 /* Initialize structures/registers */
419 ubi32_rd = kzalloc(sizeof(struct ubi32_snd_runtime_data), GFP_KERNEL);
420 if (ubi32_rd == NULL) {
421 ret = -ENOMEM;
422 goto out;
423 }
424
425 runtime->private_data = ubi32_rd;
426
427 #ifdef CONFIG_SND_DEBUG
428 snd_printk(KERN_INFO "snd_ubi32_pcm_open returned 0\n");
429 #endif
430
431 return 0;
432 out:
433 #ifdef CONFIG_SND_DEBUG
434 snd_printk(KERN_INFO "snd_ubi32_pcm_open returned %d\n", ret);
435 #endif
436
437 return ret;
438 }
439
440 static struct snd_pcm_ops snd_ubi32_pcm_ops = {
441 .open = snd_ubi32_pcm_open, /* Open */
442 .close = snd_ubi32_pcm_close, /* Close */
443 .ioctl = snd_pcm_lib_ioctl, /* Generic IOCTL handler */
444 .hw_params = snd_ubi32_pcm_hw_params, /* Hardware parameters/capabilities */
445 .hw_free = snd_ubi32_pcm_hw_free, /* Free function for hw_params */
446 .prepare = snd_ubi32_pcm_prepare,
447 .trigger = snd_ubi32_pcm_trigger,
448 .pointer = snd_ubi32_pcm_pointer,
449 };
450
451 /*
452 * Interrupt handler that gets called when the audio device
453 * interrupts Linux
454 */
455 static irqreturn_t snd_ubi32_pcm_interrupt(int irq, void *appdata)
456 {
457 struct snd_pcm *pcm = (struct snd_pcm *)appdata;
458 struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
459 struct audio_dev_regs *adr = ubi32_priv->adr;
460 struct snd_pcm_substream *substream;
461 struct ubi32_snd_runtime_data *ubi32_rd;
462 int dma_to_fill = 0;
463
464 /*
465 * Check to see if the interrupt is for us
466 */
467 if (!(ubi32_priv->ar->int_status & (1 << ubi32_priv->irq_idx))) {
468 return IRQ_NONE;
469 }
470
471 /*
472 * Clear the interrupt
473 */
474 ubi32_priv->ar->int_status &= ~(1 << ubi32_priv->irq_idx);
475
476 /*
477 * We only have one stream since we don't mix. Therefore
478 * we don't need to search through substreams.
479 */
480 if (ubi32_priv->is_capture) {
481 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
482 } else {
483 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
484 }
485
486 if (!substream->runtime) {
487 snd_printk(KERN_WARNING "No runtime data\n");
488 return IRQ_NONE;
489 }
490
491 ubi32_rd = substream->runtime->private_data;
492
493 #ifdef CONFIG_SND_DEBUG
494 snd_printk(KERN_INFO "Ubi32 ALSA interrupt\n");
495 #endif
496
497 if (ubi32_rd == NULL) {
498 snd_printk(KERN_WARNING "No private data\n");
499 return IRQ_NONE;
500 }
501
502 // Check interrupt cause
503 if (0) {
504 // Handle the underflow case
505 } else if ((adr->status & AUDIO_STATUS_PLAY_DMA0_REQUEST) ||
506 (adr->status & AUDIO_STATUS_PLAY_DMA1_REQUEST)) {
507 if (adr->status & AUDIO_STATUS_PLAY_DMA0_REQUEST) {
508 dma_to_fill = 0;
509 adr->status &= ~AUDIO_STATUS_PLAY_DMA0_REQUEST;
510 } else if (adr->status & AUDIO_STATUS_PLAY_DMA1_REQUEST) {
511 dma_to_fill = 1;
512 adr->status &= ~AUDIO_STATUS_PLAY_DMA1_REQUEST;
513 }
514 ubi32_rd->period_ptr += ubi32_rd->period_size;
515 if (ubi32_rd->period_ptr >= ubi32_rd->dma_buffer_end) {
516 ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
517 }
518 adr->dma_xfer_requests[dma_to_fill].ptr = (void *)ubi32_rd->period_ptr;
519 adr->dma_xfer_requests[dma_to_fill].ctr = ubi32_rd->period_size;
520 adr->dma_xfer_requests[dma_to_fill].active = 1;
521 #ifdef CONFIG_SND_DEBUG
522 snd_printk(KERN_INFO "xfer_request %d ptr=0x%x ctr=%u\n", dma_to_fill, ubi32_rd->period_ptr, ubi32_rd->period_size);
523 #endif
524 adr->int_flags |= AUDIO_INT_FLAG_MORE_SAMPLES;
525 snd_ubi32_vp_int_set(substream->pcm);
526 }
527 // If we are interrupted by the VP, that means we completed
528 // processing one period of audio. We need to inform the upper
529 // layers of ALSA of this.
530 snd_pcm_period_elapsed(substream);
531
532 return IRQ_HANDLED;
533 }
534
535 void __devexit snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv)
536 {
537 struct snd_pcm *pcm = ubi32_priv->pcm;
538 free_irq(ubi32_priv->rx_irq, pcm);
539 }
540
541 #if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
542 #error "Change this table to match pcm.h"
543 #endif
544 static unsigned int rates[] __initdata = {5512, 8000, 11025, 16000, 22050,
545 32000, 44100, 48000, 64000, 88200,
546 96000, 176400, 192000};
547
548 /*
549 * snd_ubi32_pcm_probe
550 */
551 int __devinit snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev)
552 {
553 struct snd_pcm *pcm;
554 int ret, err;
555 int i;
556 int j;
557 int nrates;
558 unsigned int rate_max = 0;
559 unsigned int rate_min = 0xFFFFFFFF;
560 unsigned int rate_mask = 0;
561 struct audio_dev_regs *adr;
562 struct resource *res_adr;
563 struct resource *res_irq_tx;
564 struct resource *res_irq_rx;
565 struct ubi32pcm_platform_data *pdata;
566
567 pdata = pdev->dev.platform_data;
568 if (!pdata) {
569 return -ENODEV;
570 }
571
572 /*
573 * Get our resources, adr is the hardware driver base address
574 * and the tx and rx irqs are used to communicate with the
575 * hardware driver.
576 */
577 res_adr = platform_get_resource(pdev, IORESOURCE_MEM, AUDIO_MEM_RESOURCE);
578 res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIO_TX_IRQ_RESOURCE);
579 res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIO_RX_IRQ_RESOURCE);
580 if (!res_adr || !res_irq_tx || !res_irq_rx) {
581 snd_printk(KERN_WARNING "Could not get resources");
582 return -ENODEV;
583 }
584
585 ubi32_priv->ar = (struct audio_regs *)res_adr->start;
586 ubi32_priv->tx_irq = res_irq_tx->start;
587 ubi32_priv->rx_irq = res_irq_rx->start;
588 ubi32_priv->irq_idx = pdata->inst_num;
589 ubi32_priv->adr = &(ubi32_priv->ar->adr[pdata->inst_num]);
590
591 /*
592 * Check the version
593 */
594 adr = ubi32_priv->adr;
595 if (adr->version != AUDIO_DEV_REGS_VERSION) {
596 snd_printk(KERN_WARNING "This audio_dev_reg is not compatible with this driver\n");
597 return -ENODEV;
598 }
599
600 /*
601 * Find out the standard rates, also find max and min rates
602 */
603 for (i = 0; i < ARRAY_SIZE(rates); i++) {
604 int found = 0;
605 for (j = 0; j < adr->n_sample_rates; j++) {
606 if (rates[i] == adr->sample_rates[j]) {
607 /*
608 * Check to see if it is supported by the dac
609 */
610 if ((rates[i] >= ubi32_priv->min_sample_rate) &&
611 (!ubi32_priv->max_sample_rate ||
612 (ubi32_priv->max_sample_rate && (rates[i] <= ubi32_priv->max_sample_rate)))) {
613 found = 1;
614 rate_mask |= (1 << i);
615 nrates++;
616 if (rates[i] < rate_min) {
617 rate_min = rates[i];
618 }
619 if (rates[i] > rate_max) {
620 rate_max = rates[i];
621 }
622 break;
623 }
624 }
625 }
626 if (!found) {
627 rate_mask |= SNDRV_PCM_RATE_KNOT;
628 }
629 }
630
631 snd_ubi32_pcm_hw.rates = rate_mask;
632 snd_ubi32_pcm_hw.rate_min = rate_min;
633 snd_ubi32_pcm_hw.rate_max = rate_max;
634 ubi32_pcm_rates.count = adr->n_sample_rates;
635 ubi32_pcm_rates.list = (unsigned int *)adr->sample_rates;
636 ubi32_pcm_rates.mask = 0;
637
638 for (i = 0; i < 32; i++) {
639 if (adr->channel_mask & (1 << i)) {
640 if (!snd_ubi32_pcm_hw.channels_min) {
641 snd_ubi32_pcm_hw.channels_min = i;
642 }
643 snd_ubi32_pcm_hw.channels_max = i;
644 }
645 }
646 snd_printk(KERN_INFO "Ubi32PCM: channels_min:%u channels_max:%u\n",
647 snd_ubi32_pcm_hw.channels_min,
648 snd_ubi32_pcm_hw.channels_max);
649
650 if (adr->caps & AUDIONODE_CAP_BE) {
651 snd_ubi32_pcm_hw.formats |= SNDRV_PCM_FMTBIT_S16_BE;
652 }
653 if (adr->caps & AUDIONODE_CAP_LE) {
654 snd_ubi32_pcm_hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
655 }
656
657 snd_printk(KERN_INFO "Ubi32PCM: rates:%08x min:%u max:%u count:%d fmts:%016llx (%s)\n",
658 snd_ubi32_pcm_hw.rates,
659 snd_ubi32_pcm_hw.rate_min,
660 snd_ubi32_pcm_hw.rate_max,
661 ubi32_pcm_rates.count,
662 snd_ubi32_pcm_hw.formats,
663 ubi32_priv->is_capture ? "capture" : "playback");
664
665 if (ubi32_priv->is_capture) {
666 ret = snd_pcm_new(ubi32_priv->card, "Ubi32 PCM", 0, 0, 1, &pcm);
667 } else {
668 ret = snd_pcm_new(ubi32_priv->card, "Ubi32 PCM", 0, 1, 0, &pcm);
669 }
670
671 if (ret < 0) {
672 return ret;
673 }
674
675 pcm->private_data = ubi32_priv;
676 ubi32_priv->pcm = pcm;
677 ubi32_priv->pdata = pdata;
678
679 pcm->info_flags = 0;
680
681 strcpy(pcm->name, "Ubi32-PCM");
682
683 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
684 snd_dma_continuous_data(GFP_KERNEL),
685 45*1024, 64*1024);
686
687 if (ubi32_priv->is_capture) {
688 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ubi32_pcm_ops);
689 } else {
690 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ubi32_pcm_ops);
691 }
692
693 /*
694 * Start up the audio device
695 */
696 adr->int_flags |= AUDIO_INT_FLAG_COMMAND;
697 adr->command = AUDIO_CMD_ENABLE;
698 snd_ubi32_vp_int_set(pcm);
699
700 /*
701 * Request IRQ
702 */
703 err = request_irq(ubi32_priv->rx_irq, snd_ubi32_pcm_interrupt, IRQF_SHARED | IRQF_DISABLED, pcm->name, pcm);
704 if (err) {
705 snd_printk(KERN_WARNING "request_irq failed: irq=%d err=%d\n", ubi32_priv->rx_irq, err);
706 return -ENODEV;
707 }
708
709 return ret;
710
711 }