source: rtems/c/src/lib/libbsp/arm/nds/sound/sound.c @ c193baad

4.104.11
Last change on this file since c193baad was c193baad, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Apr 9, 2010 at 8:24:57 PM

unify irq data types and code, merge s3c2400/s3c2410 support

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * RTEMS for Nintendo DS sound driver.
3 *
4 * Copyright (c) 2008 by Matthieu Bucchianeri <mbucchia@gmail.com>
5 *
6 * The license and distribution terms for this file may be
7 * found in the file LICENSE in this distribution or at
8 *
9 * http://www.rtems.com/license/LICENSE
10 *
11 * $Id$
12 */
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <errno.h>
17#include <sys/types.h>
18
19#include <bsp.h>
20#include <rtems/irq.h>
21#include <rtems/libio.h>
22#include <nds.h>
23
24#include "sound.h"
25#include "../include/my_ipc.h"
26
27/*
28 * default values.
29 */
30
31static int volume = 64;
32static int pan = 64;
33static int freq = 11025;
34static int format = 0;          // 0 is 8 bits and 1 is 16 bits
35static int offset = 0;
36
37/*
38 * sound device driver initialize entry point.
39 */
40
41rtems_device_driver
42sound_initialize (rtems_device_major_number major,
43                  rtems_device_minor_number minor, void *arg)
44{
45  rtems_status_code status;
46
47  printk ("[+] sound started\n");
48
49  /* register the devices */
50  status = rtems_io_register_name ("/dev/pcm", major, 0);
51  if (status != RTEMS_SUCCESSFUL) {
52    printk ("[!] error registering sound\n");
53    rtems_fatal_error_occurred (status);
54  }
55
56  /* reset IPCs structs */
57  IPC->soundData = NULL;
58  memset ((void *)my_IPC, 0, sizeof (*my_IPC));
59  DC_FlushAll ();
60
61  return RTEMS_SUCCESSFUL;
62}
63
64/*
65 * sound device driver open operation.
66 */
67
68rtems_device_driver
69sound_open (rtems_device_major_number major,
70            rtems_device_minor_number minor, void *arg)
71{
72  return RTEMS_SUCCESSFUL;
73}
74
75/*
76 * sound device driver close operation.
77 */
78
79rtems_device_driver
80sound_close (rtems_device_major_number major,
81             rtems_device_minor_number minor, void *arg)
82{
83  return RTEMS_SUCCESSFUL;
84}
85
86/*
87 * sound device driver read operation. read data from recorded microphone
88 * samples.
89 */
90
91rtems_device_driver
92sound_read (rtems_device_major_number major,
93            rtems_device_minor_number minor, void *arg)
94{
95  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
96
97  /* check end of file */
98  if (offset >= my_IPC->recorded_length) {
99    rw_args->bytes_moved = 0;
100
101    return RTEMS_SUCCESSFUL;
102  }
103
104  /* read buffer */
105  memcpy ((void *)rw_args->buffer, (void *)my_IPC->record_buffer + offset, rw_args->count);
106  offset += rw_args->count;
107  rw_args->bytes_moved = rw_args->count;
108  return RTEMS_SUCCESSFUL;
109}
110
111/*
112 * sound device driver write operation. read a pcm sound.
113 */
114
115rtems_device_driver
116sound_write (rtems_device_major_number major,
117             rtems_device_minor_number minor, void *arg)
118{
119  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
120  static TransferSound snd;
121
122  /* XXX not exclusive */
123  while (IPC->soundData != NULL);
124
125  snd.count = 1;
126  snd.data[0].data = rw_args->buffer;
127  snd.data[0].len = rw_args->count;
128  snd.data[0].rate = freq;
129  snd.data[0].vol = volume;
130  snd.data[0].pan = pan;
131  snd.data[0].format = format;
132
133  IPC->soundData = &snd;
134  DC_FlushAll ();
135
136  rw_args->bytes_moved = rw_args->count;
137  return RTEMS_SUCCESSFUL;
138}
139
140/*
141 * ioctl entry point.
142 */
143
144rtems_device_driver
145sound_control (rtems_device_major_number major,
146               rtems_device_minor_number minor, void *arg)
147{
148  rtems_libio_ioctl_args_t *args = arg;
149  uint32_t *val = (uint32_t *) args->buffer;
150
151  switch (args->command) {
152    /* sound volume management */
153  case SOUND_SVOL:
154    volume = *val;
155    break;
156  case SOUND_GVOL:
157    *val = volume;
158    break;
159    /* sound format settings */
160  case SOUND_SFMT:
161    switch (*val & SOUND_FREQ_MASK) {
162    case SOUND_FREQ_11025:
163      freq = 11025;
164      break;
165    case SOUND_FREQ_22050:
166      freq = 22050;
167      break;
168    case SOUND_FREQ_44100:
169      freq = 44100;
170      break;
171    case SOUND_FREQ_RECORD:
172      freq = 16384;
173      break;
174    }
175    format = (*val & SOUND_FORMAT_16) ? 1 : 0;
176    printk ("[+] pcm %d bits @ %d hz\n", format ? 16 : 8, freq);
177    break;
178  case SOUND_GFMT:
179    if (freq == 11025) {
180      *val = SOUND_FREQ_11025;
181    } else if (freq == 22050) {
182      *val = SOUND_FREQ_22050;
183    } else if (freq == 44100) {
184      *val = SOUND_FREQ_44100;
185    } else if (freq == 16384) {
186      *val = SOUND_FREQ_RECORD;
187    }
188    *val |= format ? SOUND_FORMAT_16 : SOUND_FORMAT_8;
189    break;
190    /* sound pan settings */
191  case SOUND_SPAN:
192    pan = *val;
193    break;
194  case SOUND_GPAN:
195    *val = pan;
196    break;
197    /* set recording buffer length */
198  case SOUND_SRECLEN:
199    my_IPC->record_buffer = malloc (*val);
200    my_IPC->record_length_max = *val;
201    printk ("[+] mic buffer %u B @ %p\n", my_IPC->record_length_max,
202            my_IPC->record_buffer);
203    break;
204    /* start recording */
205  case SOUND_STARTREC:
206    my_IPC->recorded_length = 0;
207    my_IPC->record = 1;
208    break;
209    /* stop recording */
210  case SOUND_STOPREC:
211    if (!my_IPC->record) {
212      printk ("[!] STOPREC while not recording\n");
213    }
214    my_IPC->record = 0;
215    while (my_IPC->recorded_length == 0);
216    offset = 0;
217    if (val != NULL) {
218      *val = my_IPC->recorded_length;
219    }
220    break;
221  default:
222    break;
223  }
224  return RTEMS_SUCCESSFUL;
225}
Note: See TracBrowser for help on using the repository browser.