pxa-audio.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:20k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/sound/pxa-audio.c -- audio interface for the Cotula chip
  3.  *
  4.  *  Author: Nicolas Pitre
  5.  *  Created: Aug 15, 2001
  6.  *  Copyright: MontaVista Software Inc.
  7.  *
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License version 2 as
  10.  *  published by the Free Software Foundation.
  11.  */
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/slab.h>
  16. #include <linux/pci.h>
  17. #include <linux/poll.h>
  18. #include <linux/sound.h>
  19. #include <linux/soundcard.h>
  20. #include <asm/hardware.h>
  21. #include <asm/irq.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/semaphore.h>
  24. #include <asm/dma.h>
  25. #include "pxa-audio.h"
  26. #define AUDIO_NBFRAGS_DEFAULT 8
  27. #define AUDIO_FRAGSIZE_DEFAULT 8192
  28. #define MAX_DMA_SIZE 4096
  29. #define DMA_DESC_SIZE sizeof(pxa_dma_desc)
  30. /*
  31.  * This function frees all buffers
  32.  */
  33. #define audio_clear_buf pxa_audio_clear_buf
  34. void pxa_audio_clear_buf(audio_stream_t * s)
  35. {
  36. DECLARE_WAITQUEUE(wait, current);
  37. int frag;
  38. if (!s->buffers)
  39. return;
  40. /* Ensure DMA isn't running */
  41. set_current_state(TASK_UNINTERRUPTIBLE);
  42. add_wait_queue(&s->stop_wq, &wait);
  43. DCSR(s->dma_ch) = DCSR_STOPIRQEN;
  44. schedule();
  45. remove_wait_queue(&s->stop_wq, &wait);
  46. /* free DMA buffers */
  47. for (frag = 0; frag < s->nbfrags; frag++) {
  48. audio_buf_t *b = &s->buffers[frag];
  49. if (!b->master)
  50. continue;
  51. consistent_free(b->data, b->master, b->dma_desc->dsadr);
  52. }
  53. /* free descriptor ring */
  54. if (s->buffers->dma_desc)
  55. consistent_free(s->buffers->dma_desc, 
  56. s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE,
  57. s->dma_desc_phys);
  58. /* free buffer structure array */
  59. kfree(s->buffers);
  60. s->buffers = NULL;
  61. }
  62. /*
  63.  * This function allocates the DMA descriptor array and buffer data space
  64.  * according to the current number of fragments and fragment size.
  65.  */
  66. static int audio_setup_buf(audio_stream_t * s)
  67. {
  68. pxa_dma_desc *dma_desc;
  69. dma_addr_t dma_desc_phys;
  70. int nb_desc, frag, i, buf_size = 0;
  71. char *dma_buf = NULL;
  72. dma_addr_t dma_buf_phys = 0;
  73. if (s->buffers)
  74. return -EBUSY;
  75. /* Our buffer structure array */
  76. s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
  77. if (!s->buffers)
  78. goto err;
  79. memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags);
  80. /* 
  81.  * Our DMA descriptor array:
  82.  * for Each fragment we have one checkpoint descriptor plus one 
  83.  * descriptor per MAX_DMA_SIZE byte data blocks.
  84.  */
  85. nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags;
  86. dma_desc = consistent_alloc(GFP_KERNEL,
  87.     nb_desc * DMA_DESC_SIZE,
  88.     &dma_desc_phys);
  89. if (!dma_desc)
  90. goto err;
  91. s->descs_per_frag = nb_desc / s->nbfrags;
  92. s->buffers->dma_desc = dma_desc;
  93. s->dma_desc_phys = dma_desc_phys;
  94. for (i = 0; i < nb_desc - 1; i++)
  95. dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE;
  96. dma_desc[i].ddadr = dma_desc_phys;
  97. /* Our actual DMA buffers */
  98. for (frag = 0; frag < s->nbfrags; frag++) {
  99. audio_buf_t *b = &s->buffers[frag];
  100. /*
  101.  * Let's allocate non-cached memory for DMA buffers.
  102.  * We try to allocate all memory at once.
  103.  * If this fails (a common reason is memory fragmentation),
  104.  * then we'll try allocating smaller buffers.
  105.  */
  106. if (!buf_size) {
  107. buf_size = (s->nbfrags - frag) * s->fragsize;
  108. do {
  109. dma_buf = consistent_alloc(GFP_KERNEL,
  110.    buf_size, 
  111.    &dma_buf_phys);
  112. if (!dma_buf)
  113. buf_size -= s->fragsize;
  114. } while (!dma_buf && buf_size);
  115. if (!dma_buf)
  116. goto err;
  117. b->master = buf_size;
  118. memzero(dma_buf, buf_size);
  119. }
  120. /* 
  121.  * Set up our checkpoint descriptor.  Since the count 
  122.  * is always zero, we'll abuse the dsadr and dtadr fields
  123.  * just in case this one is picked up by the hardware
  124.  * while processing SOUND_DSP_GETPTR.
  125.  */
  126. dma_desc->dsadr = dma_buf_phys;
  127. dma_desc->dtadr = dma_buf_phys;
  128. dma_desc->dcmd = DCMD_ENDIRQEN;
  129. if (s->output && !s->mapped)
  130. dma_desc->ddadr |= DDADR_STOP;
  131. b->dma_desc = dma_desc++;
  132. /* set up the actual data descriptors */
  133. for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) {
  134. dma_desc[i].dsadr = (s->output) ?
  135. (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr;
  136. dma_desc[i].dtadr = (s->output) ?
  137. s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE);
  138. dma_desc[i].dcmd = s->dcmd |
  139. ((s->fragsize < MAX_DMA_SIZE) ?
  140. s->fragsize : MAX_DMA_SIZE);
  141. }
  142. dma_desc += i;
  143. /* handle buffer pointers */
  144. b->data = dma_buf;
  145. dma_buf += s->fragsize;
  146. dma_buf_phys += s->fragsize;
  147. buf_size -= s->fragsize;
  148. }
  149. s->usr_frag = s->dma_frag = 0;
  150. s->bytecount = 0;
  151. s->fragcount = 0;
  152. sema_init(&s->sem, (s->output) ? s->nbfrags : 0);
  153. return 0;
  154. err:
  155. printk("pxa-audio: unable to allocate audio memoryn ");
  156. audio_clear_buf(s);
  157. return -ENOMEM;
  158. }
  159. /*
  160.  * Our DMA interrupt handler
  161.  */
  162. static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs)
  163. {
  164. audio_stream_t *s = dev_id;
  165. u_int dcsr;
  166. dcsr = DCSR(ch);
  167. DCSR(ch) = dcsr & ~DCSR_STOPIRQEN;
  168. if (!s->buffers) {
  169. printk("AC97 DMA: wow... received IRQ for channel %d but no buffer existsn", ch);
  170. return;
  171. }
  172. if (dcsr & DCSR_BUSERR)
  173. printk("AC97 DMA: bus error interrupt on channel %dn", ch);
  174. if (dcsr & DCSR_ENDINTR) {
  175. u_long cur_dma_desc;
  176. u_int cur_dma_frag;
  177. /* 
  178.  * Find out which DMA desc is current.  Note that DDADR
  179.  * points to the next desc, not the current one.
  180.  */
  181. cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE;
  182. /*
  183.  * Let the compiler nicely optimize constant divisors into
  184.  * multiplications for the common cases which is much faster.
  185.  * Common cases: x = 1 + (1 << y) for y = [0..3]
  186.  */
  187. switch (s->descs_per_frag) {
  188. case 2:  cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break;
  189. case 3:  cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break;
  190. case 5:  cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break;
  191. case 9:  cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break;
  192. default: cur_dma_frag =
  193.     cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE);
  194. }
  195. /* Account for possible wrap back of cur_dma_desc above */
  196. if (cur_dma_frag >= s->nbfrags)
  197. cur_dma_frag = s->nbfrags - 1;
  198. while (s->dma_frag != cur_dma_frag) {
  199. if (!s->mapped) {
  200. /* 
  201.  * This fragment is done - set the checkpoint
  202.  * descriptor to STOP until it is gets
  203.  * processed by the read or write function.
  204.  */
  205. s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP;
  206. up(&s->sem);
  207. }
  208. if (++s->dma_frag >= s->nbfrags)
  209. s->dma_frag = 0;
  210. /* Accounting */
  211. s->bytecount += s->fragsize;
  212. s->fragcount++;
  213. }
  214. /* ... and for polling processes */
  215. wake_up(&s->frag_wq);
  216. }
  217. if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE))
  218. wake_up(&s->stop_wq);
  219. }
  220. /*
  221.  * Validate and sets up buffer fragments, etc.
  222.  */
  223. static int audio_set_fragments(audio_stream_t *s, int val)
  224. {
  225. if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN)
  226. return -EBUSY;
  227. if (s->buffers)
  228. audio_clear_buf(s);
  229. s->nbfrags = (val >> 16) & 0x7FFF;
  230. val &= 0xffff;
  231. if (val < 5)
  232. val = 5;
  233. if (val > 15)
  234. val = 15;
  235. s->fragsize = 1 << val;
  236. if (s->nbfrags < 2)
  237. s->nbfrags = 2;
  238. if (s->nbfrags * s->fragsize > 256 * 1024)
  239. s->nbfrags = 256 * 1024 / s->fragsize;
  240. if (audio_setup_buf(s))
  241. return -ENOMEM;
  242. return val|(s->nbfrags << 16);
  243. }
  244. /*
  245.  * The fops functions
  246.  */
  247. static int audio_write(struct file *file, const char *buffer,
  248.        size_t count, loff_t * ppos)
  249. {
  250. const char *buffer0 = buffer;
  251. audio_state_t *state = (audio_state_t *)file->private_data;
  252. audio_stream_t *s = state->output_stream;
  253. int chunksize, ret = 0;
  254. if (ppos != &file->f_pos)
  255. return -ESPIPE;
  256. if (s->mapped)
  257. return -ENXIO;
  258. if (!s->buffers && audio_setup_buf(s))
  259. return -ENOMEM;
  260. while (count > 0) {
  261. audio_buf_t *b = &s->buffers[s->usr_frag];
  262. /* Grab a fragment */
  263. if (file->f_flags & O_NONBLOCK) {
  264. ret = -EAGAIN;
  265. if (down_trylock(&s->sem))
  266. break;
  267. } else {
  268. ret = -ERESTARTSYS;
  269. if (down_interruptible(&s->sem))
  270. break;
  271. }
  272. /* Feed the current buffer */
  273. chunksize = s->fragsize - b->offset;
  274. if (chunksize > count)
  275. chunksize = count;
  276. if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
  277. up(&s->sem);
  278. return -EFAULT;
  279. }
  280. b->offset += chunksize;
  281. buffer += chunksize;
  282. count -= chunksize;
  283. if (b->offset < s->fragsize) {
  284. up(&s->sem);
  285. break;
  286. }
  287. /* 
  288.  * Activate DMA on current buffer.
  289.  * We unlock this fragment's checkpoint descriptor and
  290.  * kick DMA if it is idle.  Using checkpoint descriptors
  291.  * allows for control operations without the need for 
  292.  * stopping the DMA channel if it is already running.
  293.  */
  294. b->offset = 0;
  295. b->dma_desc->ddadr &= ~DDADR_STOP;
  296. if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
  297. DDADR(s->dma_ch) = b->dma_desc->ddadr;
  298. DCSR(s->dma_ch) = DCSR_RUN;
  299. }
  300. /* move the index to the next fragment */
  301. if (++s->usr_frag >= s->nbfrags)
  302. s->usr_frag = 0;
  303. }
  304. if ((buffer - buffer0))
  305. ret = buffer - buffer0;
  306. return ret;
  307. }
  308. static int audio_read(struct file *file, char *buffer,
  309.       size_t count, loff_t * ppos)
  310. {
  311. char *buffer0 = buffer;
  312. audio_state_t *state = file->private_data;
  313. audio_stream_t *s = state->input_stream;
  314. int chunksize, ret = 0;
  315. if (ppos != &file->f_pos)
  316. return -ESPIPE;
  317. if (s->mapped)
  318. return -ENXIO;
  319. if (!s->buffers && audio_setup_buf(s))
  320. return -ENOMEM;
  321. while (count > 0) {
  322. audio_buf_t *b = &s->buffers[s->usr_frag];
  323. /* prime DMA */
  324. if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
  325. DDADR(s->dma_ch) = 
  326. s->buffers[s->dma_frag].dma_desc->ddadr;
  327. DCSR(s->dma_ch) = DCSR_RUN;
  328. }
  329. /* Wait for a buffer to become full */
  330. if (file->f_flags & O_NONBLOCK) {
  331. ret = -EAGAIN;
  332. if (down_trylock(&s->sem))
  333. break;
  334. } else {
  335. ret = -ERESTARTSYS;
  336. if (down_interruptible(&s->sem))
  337. break;
  338. }
  339. /* Grab data from current buffer */
  340. chunksize = s->fragsize - b->offset;
  341. if (chunksize > count)
  342. chunksize = count;
  343. if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
  344. up(&s->sem);
  345. return -EFAULT;
  346. }
  347. b->offset += chunksize;
  348. buffer += chunksize;
  349. count -= chunksize;
  350. if (b->offset < s->fragsize) {
  351. up(&s->sem);
  352. break;
  353. }
  354. /* 
  355.  * Make this buffer available for DMA again.
  356.  * We unlock this fragment's checkpoint descriptor and
  357.  * kick DMA if it is idle.  Using checkpoint descriptors
  358.  * allows for control operations without the need for 
  359.  * stopping the DMA channel if it is already running.
  360.  */
  361. b->offset = 0;
  362. b->dma_desc->ddadr &= ~DDADR_STOP;
  363. /* move the index to the next fragment */
  364. if (++s->usr_frag >= s->nbfrags)
  365. s->usr_frag = 0;
  366. }
  367. if ((buffer - buffer0))
  368. ret = buffer - buffer0;
  369. return ret;
  370. }
  371. static int audio_sync(struct file *file)
  372. {
  373. audio_state_t *state = file->private_data;
  374. audio_stream_t *s = state->output_stream;
  375. audio_buf_t *b;
  376. pxa_dma_desc *final_desc;
  377. u_long dcmd_save = 0;
  378. DECLARE_WAITQUEUE(wait, current);
  379. if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped)
  380. return 0;
  381. /*
  382.  * Send current buffer if it contains data.  Be sure to send
  383.  * a full sample count.
  384.  */
  385. final_desc = NULL;
  386. b = &s->buffers[s->usr_frag];
  387. if (b->offset &= ~3) {
  388. final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE];
  389. b->offset &= (MAX_DMA_SIZE-1);
  390. dcmd_save = final_desc->dcmd;
  391. final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN; 
  392. final_desc->ddadr |= DDADR_STOP;
  393. b->offset = 0;
  394. b->dma_desc->ddadr &= ~DDADR_STOP;
  395. if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
  396. DDADR(s->dma_ch) = b->dma_desc->ddadr;
  397. DCSR(s->dma_ch) = DCSR_RUN;
  398. }
  399. }
  400. /* Wait for DMA to complete. */
  401. set_current_state(TASK_INTERRUPTIBLE);
  402. #if 0
  403. /* 
  404.  * The STOPSTATE IRQ never seem to occur if DCSR_STOPIRQEN is set
  405.  * along wotj DCSR_RUN.  Silicon bug?
  406.  */
  407. add_wait_queue(&s->stop_wq, &wait);
  408. DCSR(s->dma_ch) |= DCSR_STOPIRQEN;
  409. schedule();
  410. #else 
  411. add_wait_queue(&s->frag_wq, &wait);
  412. while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) {
  413. schedule();
  414. set_current_state(TASK_INTERRUPTIBLE);
  415. }
  416. #endif
  417. set_current_state(TASK_RUNNING);
  418. remove_wait_queue(&s->frag_wq, &wait);
  419. /* Restore the descriptor chain. */
  420. if (final_desc) {
  421. final_desc->dcmd = dcmd_save;
  422. final_desc->ddadr &= ~DDADR_STOP;
  423. b->dma_desc->ddadr |= DDADR_STOP;
  424. }
  425. return 0;
  426. }
  427. static unsigned int audio_poll(struct file *file,
  428.        struct poll_table_struct *wait)
  429. {
  430. audio_state_t *state = file->private_data;
  431. audio_stream_t *is = state->input_stream;
  432. audio_stream_t *os = state->output_stream;
  433. unsigned int mask = 0;
  434. if (file->f_mode & FMODE_READ) {
  435. /* Start audio input if not already active */
  436. if (!is->buffers && audio_setup_buf(is))
  437. return -ENOMEM;
  438. if (DCSR(is->dma_ch) & DCSR_STOPSTATE) {
  439. DDADR(is->dma_ch) = 
  440. is->buffers[is->dma_frag].dma_desc->ddadr;
  441. DCSR(is->dma_ch) = DCSR_RUN;
  442. }
  443. poll_wait(file, &is->frag_wq, wait);
  444. }
  445. if (file->f_mode & FMODE_WRITE) {
  446. if (!os->buffers && audio_setup_buf(os))
  447. return -ENOMEM;
  448. poll_wait(file, &os->frag_wq, wait);
  449. }
  450. if (file->f_mode & FMODE_READ)
  451. if (( is->mapped && is->bytecount > 0) ||
  452.     (!is->mapped && atomic_read(&is->sem.count) > 0))
  453. mask |= POLLIN | POLLRDNORM;
  454. if (file->f_mode & FMODE_WRITE)
  455. if (( os->mapped && os->bytecount > 0) ||
  456.     (!os->mapped && atomic_read(&os->sem.count) > 0))
  457. mask |= POLLOUT | POLLWRNORM;
  458. return mask;
  459. }
  460. static int audio_ioctl( struct inode *inode, struct file *file,
  461. uint cmd, ulong arg)
  462. {
  463. audio_state_t *state = file->private_data;
  464. audio_stream_t *os = state->output_stream;
  465. audio_stream_t *is = state->input_stream;
  466. long val;
  467. switch (cmd) {
  468. case OSS_GETVERSION:
  469. return put_user(SOUND_VERSION, (int *)arg);
  470. case SNDCTL_DSP_GETBLKSIZE:
  471. if (file->f_mode & FMODE_WRITE)
  472. return put_user(os->fragsize, (int *)arg);
  473. else
  474. return put_user(is->fragsize, (int *)arg);
  475. case SNDCTL_DSP_GETCAPS:
  476. val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
  477. if (is && os)
  478. val |= DSP_CAP_DUPLEX;
  479. return put_user(val, (int *)arg);
  480. case SNDCTL_DSP_SETFRAGMENT:
  481. if (get_user(val, (long *) arg))
  482. return -EFAULT;
  483. if (file->f_mode & FMODE_READ) {
  484. int ret = audio_set_fragments(is, val);
  485. if (ret < 0)
  486. return ret;
  487. ret = put_user(ret, (int *)arg);
  488. if (ret)
  489. return ret;
  490. }
  491. if (file->f_mode & FMODE_WRITE) {
  492. int ret = audio_set_fragments(os, val);
  493. if (ret < 0)
  494. return ret;
  495. ret = put_user(ret, (int *)arg);
  496. if (ret)
  497. return ret;
  498. }
  499. return 0;
  500. case SNDCTL_DSP_SYNC:
  501. return audio_sync(file);
  502. case SNDCTL_DSP_SETDUPLEX:
  503. return 0;
  504. case SNDCTL_DSP_POST:
  505. return 0;
  506. case SNDCTL_DSP_GETTRIGGER:
  507. val = 0;
  508. if (file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN)
  509. val |= PCM_ENABLE_INPUT;
  510. if (file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN)
  511. val |= PCM_ENABLE_OUTPUT;
  512. return put_user(val, (int *)arg);
  513. case SNDCTL_DSP_SETTRIGGER:
  514. if (get_user(val, (int *)arg))
  515. return -EFAULT;
  516. if (file->f_mode & FMODE_READ) {
  517. if (val & PCM_ENABLE_INPUT) {
  518. if (!is->buffers && audio_setup_buf(is))
  519. return -ENOMEM;
  520. if (!(DCSR(is->dma_ch) & DCSR_RUN)) {
  521. audio_buf_t *b = &is->buffers[is->dma_frag];
  522. DDADR(is->dma_ch) = b->dma_desc->ddadr;
  523. DCSR(is->dma_ch) = DCSR_RUN;
  524. }
  525. } else {
  526. DCSR(is->dma_ch) = 0;
  527. }
  528. }
  529. if (file->f_mode & FMODE_WRITE) {
  530. if (val & PCM_ENABLE_OUTPUT) {
  531. if (!os->buffers && audio_setup_buf(os))
  532. return -ENOMEM;
  533. if (!(DCSR(os->dma_ch) & DCSR_RUN)) {
  534. audio_buf_t *b = &os->buffers[os->dma_frag];
  535. DDADR(os->dma_ch) = b->dma_desc->ddadr;
  536. DCSR(os->dma_ch) = DCSR_RUN;
  537. }
  538. } else {
  539. DCSR(os->dma_ch) = 0;
  540. }
  541. }
  542. return 0;
  543. case SNDCTL_DSP_GETOSPACE:
  544. case SNDCTL_DSP_GETISPACE:
  545.     {
  546. audio_buf_info inf = { 0, };
  547. audio_stream_t *s = (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
  548. if ((s == is && !(file->f_mode & FMODE_READ)) ||
  549.     (s == os && !(file->f_mode & FMODE_WRITE)))
  550. return -EINVAL;
  551. if (!s->buffers && audio_setup_buf(s))
  552. return -ENOMEM;
  553. inf.bytes = atomic_read(&s->sem.count) * s->fragsize;
  554. inf.bytes -= s->buffers[s->usr_frag].offset;
  555. inf.fragments = inf.bytes / s->fragsize;
  556. inf.fragsize = s->fragsize;
  557. inf.fragstotal = s->nbfrags;
  558. return copy_to_user((void *)arg, &inf, sizeof(inf));
  559.     }
  560. case SNDCTL_DSP_GETOPTR:
  561. case SNDCTL_DSP_GETIPTR:
  562.     {
  563. count_info inf = { 0, };
  564. audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
  565. dma_addr_t ptr;
  566. int bytecount, offset, flags;
  567. if ((s == is && !(file->f_mode & FMODE_READ)) ||
  568.     (s == os && !(file->f_mode & FMODE_WRITE)))
  569. return -EINVAL;
  570. if (DCSR(s->dma_ch) & DCSR_RUN) {
  571. audio_buf_t *b;
  572. save_flags_cli(flags);
  573. ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch);
  574. b = &s->buffers[s->dma_frag];
  575. offset = ptr - b->dma_desc->dsadr;
  576. if (offset >= s->fragsize)
  577. offset = s->fragsize - 4;
  578. } else {
  579. save_flags(flags);
  580. offset = 0;
  581. }
  582. inf.ptr = s->dma_frag * s->fragsize + offset;
  583. bytecount = s->bytecount + offset;
  584. s->bytecount = -offset;
  585. inf.blocks = s->fragcount;
  586. s->fragcount = 0;
  587. restore_flags(flags);
  588. if (bytecount < 0)
  589. bytecount = 0;
  590. inf.bytes = bytecount;
  591. return copy_to_user((void *)arg, &inf, sizeof(inf));
  592.     }
  593. case SNDCTL_DSP_NONBLOCK:
  594. file->f_flags |= O_NONBLOCK;
  595. return 0;
  596. case SNDCTL_DSP_RESET:
  597. if (file->f_mode & FMODE_WRITE) 
  598. audio_clear_buf(os);
  599. if (file->f_mode & FMODE_READ)
  600. audio_clear_buf(is);
  601. return 0;
  602. default:
  603. return state->client_ioctl(inode, file, cmd, arg);
  604. }
  605. return 0;
  606. }
  607. static int audio_mmap(struct file *file, struct vm_area_struct *vma)
  608. {
  609. audio_state_t *state = file->private_data;
  610. audio_stream_t *s;
  611. unsigned long size, vma_addr;
  612. int i, ret;
  613. if (vma->vm_pgoff != 0)
  614. return -EINVAL;
  615. if (vma->vm_flags & VM_WRITE) {
  616. if (!state->wr_ref)
  617. return -EINVAL;;
  618. s = state->output_stream;
  619. } else if (vma->vm_flags & VM_READ) {
  620. if (!state->rd_ref)
  621. return -EINVAL;
  622. s = state->input_stream;
  623. } else return -EINVAL;
  624. if (s->mapped)
  625. return -EINVAL;
  626. size = vma->vm_end - vma->vm_start;
  627. if (size != s->fragsize * s->nbfrags)
  628. return -EINVAL;
  629. if (!s->buffers && audio_setup_buf(s))
  630. return -ENOMEM;
  631. vma_addr = vma->vm_start;
  632. for (i = 0; i < s->nbfrags; i++) {
  633. audio_buf_t *buf = &s->buffers[i];
  634. if (!buf->master)
  635. continue;
  636. ret = remap_page_range(vma_addr, buf->dma_desc->dsadr,
  637.        buf->master, vma->vm_page_prot);
  638. if (ret)
  639. return ret;
  640. vma_addr += buf->master;
  641. }
  642. for (i = 0; i < s->nbfrags; i++)
  643. s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP;
  644. s->mapped = 1;
  645. return 0;
  646. }
  647. static int audio_release(struct inode *inode, struct file *file)
  648. {
  649. audio_state_t *state = file->private_data;
  650. down(&state->sem);
  651. if (file->f_mode & FMODE_READ) {
  652. audio_clear_buf(state->input_stream);
  653. *state->input_stream->drcmr = 0;
  654. pxa_free_dma(state->input_stream->dma_ch);
  655. state->rd_ref = 0;
  656. }
  657. if (file->f_mode & FMODE_WRITE) {
  658. audio_sync(file);
  659. audio_clear_buf(state->output_stream);
  660. *state->output_stream->drcmr = 0;
  661. pxa_free_dma(state->output_stream->dma_ch);
  662. state->wr_ref = 0;
  663. }
  664. up(&state->sem);
  665. return 0;
  666. }
  667. int pxa_audio_attach(struct inode *inode, struct file *file,
  668.  audio_state_t *state)
  669. {
  670. audio_stream_t *is = state->input_stream;
  671. audio_stream_t *os = state->output_stream;
  672. int err;
  673. down(&state->sem);
  674. /* access control */
  675. err = -ENODEV;
  676. if ((file->f_mode & FMODE_WRITE) && !os)
  677. goto out;
  678. if ((file->f_mode & FMODE_READ) && !is)
  679. goto out;
  680. err = -EBUSY;
  681. if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
  682. goto out;
  683. if ((file->f_mode & FMODE_READ) && state->rd_ref)
  684. goto out;
  685. /* request DMA channels */
  686. if (file->f_mode & FMODE_WRITE) {
  687. err = pxa_request_dma(os->name, DMA_PRIO_LOW, 
  688.   audio_dma_irq, os);
  689. if (err < 0)
  690. goto out;
  691. os->dma_ch = err;
  692. }
  693. if (file->f_mode & FMODE_READ) {
  694. err = pxa_request_dma(is->name, DMA_PRIO_LOW,
  695.   audio_dma_irq, is);
  696. if (err < 0) {
  697. if (file->f_mode & FMODE_WRITE) {
  698. *os->drcmr = 0;
  699. pxa_free_dma(os->dma_ch);
  700. }
  701. goto out;
  702. }
  703. is->dma_ch = err;
  704. }
  705. file->private_data = state;
  706. file->f_op->release = audio_release;
  707. file->f_op->write = audio_write;
  708. file->f_op->read = audio_read;
  709. file->f_op->mmap = audio_mmap;
  710. file->f_op->poll = audio_poll;
  711. file->f_op->ioctl = audio_ioctl;
  712. file->f_op->llseek = no_llseek;
  713. if ((file->f_mode & FMODE_WRITE)) {
  714. state->wr_ref = 1;
  715. os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
  716. os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
  717. os->output = 1;
  718. os->mapped = 0;
  719. init_waitqueue_head(&os->frag_wq);
  720. init_waitqueue_head(&os->stop_wq);
  721. *os->drcmr = os->dma_ch | DRCMR_MAPVLD;
  722. }
  723. if (file->f_mode & FMODE_READ) {
  724. state->rd_ref = 1;
  725. is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
  726. is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
  727. is->output = 0;
  728. is->mapped = 0;
  729. init_waitqueue_head(&is->frag_wq);
  730. init_waitqueue_head(&is->stop_wq);
  731. *is->drcmr = is->dma_ch | DRCMR_MAPVLD;
  732. }
  733. err = 0;
  734. out:
  735. up(&state->sem);
  736. return err;
  737. }
  738. EXPORT_SYMBOL(pxa_audio_attach);
  739. EXPORT_SYMBOL(pxa_audio_clear_buf);