OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [sound/] [vidc_audio.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * sound/vidc_audio.c
3
 *
4
 * Audio routines for the VIDC
5
 *
6
 * Copyright (C) 1997 Russell King
7
 */
8
#include <linux/config.h>
9
#include "sound_config.h"
10
 
11
#include "vidc.h"
12
 
13
/*
14
 * VIDC sound
15
 *
16
 * When using SERIAL SOUND mode (external DAC), the number of physical
17
 * channels is fixed at 2.  Therefore, the sample rate = vidc sample rate.
18
 */
19
 
20
#if defined(CONFIG_VIDC)
21
 
22
static int vidc_adev;
23
 
24
static int  vidc_audio_volume;
25
static int  vidc_audio_rate;
26
static char vidc_audio_bits;
27
static char vidc_audio_channels;
28
 
29
extern void vidc_update_filler (int bits, int channels);
30
 
31
int vidc_audio_get_volume (void)
32
{
33
  return vidc_audio_volume;
34
}
35
 
36
int vidc_audio_set_volume (int newvol)
37
{
38
  vidc_audio_volume = newvol;
39
  return vidc_audio_volume;
40
}
41
 
42
static int vidc_audio_set_bits (int bits)
43
{
44
  switch (bits) {
45
  case AFMT_QUERY:
46
        break;
47
  case AFMT_U8:
48
  case AFMT_S8:
49
  case AFMT_S16_LE:
50
        vidc_audio_bits = bits;
51
        vidc_update_filler (vidc_audio_bits, vidc_audio_channels);
52
        break;
53
  default:
54
        vidc_audio_bits = AFMT_S16_LE;
55
        vidc_update_filler (vidc_audio_bits, vidc_audio_channels);
56
        break;
57
  }
58
  return vidc_audio_bits;
59
}
60
 
61
static int vidc_audio_set_rate (int rate)
62
{
63
  if (rate) {
64
    int newsize, new2size;
65
    vidc_audio_rate = ((500000 / rate) + 1) >> 1;
66
    if (vidc_audio_rate < 3)
67
      vidc_audio_rate = 3;
68
    if (vidc_audio_rate > 255)
69
      vidc_audio_rate = 255;
70
    outl ((vidc_audio_rate - 2) | 0xb0000000, IO_VIDC_BASE);
71
    outl (0xb1000003, IO_VIDC_BASE);
72
    newsize = (10000 / vidc_audio_rate) & ~3;
73
    if (newsize< 208)
74
      newsize = 208;
75
    if (newsize > 4096)
76
      newsize = 4096;
77
    for (new2size = 128; new2size < newsize; new2size <<= 1);
78
    if (new2size - newsize > newsize - (new2size >> 1))
79
      new2size >>= 1;
80
    dma_bufsize = new2size;
81
  }
82
  return 250000 / vidc_audio_rate;
83
}
84
 
85
static int vidc_audio_set_channels (int channels)
86
{
87
  switch (channels) {
88
  case 0: break;
89
  case 1:
90
  case 2:
91
    vidc_audio_channels = channels;
92
    vidc_update_filler (vidc_audio_bits, vidc_audio_channels);
93
    break;
94
  default:
95
    vidc_audio_channels = 2;
96
    vidc_update_filler (vidc_audio_bits, vidc_audio_channels);
97
    break;
98
  }
99
  return vidc_audio_channels;
100
}
101
 
102
/*
103
 * Open the device
104
 *
105
 * dev  - device
106
 * mode - mode to open device (logical OR of OPEN_READ and OPEN_WRITE)
107
 *
108
 * Called when opening the DMAbuf               (dmabuf.c:259)
109
 */
110
static int
111
vidc_audio_open (int dev, int mode)
112
{
113
  if (vidc_busy)
114
    return -EBUSY;
115
 
116
  if (mode & OPEN_READ && !mode & OPEN_WRITE) {
117
    printk ("VIDCsound: This audio device doesn't have recording capability\n");
118
    return -EIO;
119
  }
120
  vidc_busy = 1;
121
  return 0;
122
}
123
 
124
/*
125
 * Close the device
126
 *
127
 * dev  - device
128
 *
129
 * Called when closing the DMAbuf               (dmabuf.c:477)
130
 *      after halt_xfer
131
 */
132
static void
133
vidc_audio_close (int dev)
134
{
135
  vidc_busy = 0;
136
}
137
 
138
static int
139
vidc_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
140
{
141
  int ret;
142
 
143
  switch (cmd) {
144
  case SOUND_PCM_WRITE_RATE:
145
    if (local)
146
      ret = vidc_audio_set_rate ((int) arg);
147
    else
148
      ret = vidc_audio_set_rate (get_user ((int *)arg));
149
    break;
150
 
151
  case SOUND_PCM_READ_RATE:
152
    ret = vidc_audio_set_rate (0);
153
    break;
154
 
155
  case SNDCTL_DSP_STEREO:
156
    if (local)
157
      ret = vidc_audio_set_channels ((int) arg + 1) - 1;
158
    else
159
      ret = vidc_audio_set_channels (get_user ((int *)arg) + 1) - 1;
160
    break;
161
 
162
  case SOUND_PCM_WRITE_CHANNELS:
163
    if (local)
164
      ret = vidc_audio_set_channels ((int) arg);
165
    else
166
      ret = vidc_audio_set_channels (get_user ((int *)arg));
167
    break;
168
 
169
  case SOUND_PCM_READ_CHANNELS:
170
    ret = vidc_audio_set_channels (0);
171
    break;
172
 
173
  case SNDCTL_DSP_SETFMT:
174
    if (local)
175
      ret = vidc_audio_set_bits ((int) arg);
176
    else
177
      ret = vidc_audio_set_bits (get_user ((int *)arg));
178
    break;
179
 
180
  case SOUND_PCM_READ_BITS:
181
    ret = vidc_audio_set_bits (0);
182
    break;
183
 
184
  case SOUND_PCM_WRITE_FILTER:
185
  case SOUND_PCM_READ_FILTER:
186
    ret = -EINVAL;
187
    break;
188
 
189
  default:
190
    ret = -EINVAL;
191
    break;
192
  }
193
  if (local)
194
    return ret;
195
  else
196
    return snd_ioctl_return ((int *)arg, ret);
197
}
198
 
199
/*
200
 * Output a block via DMA to sound device
201
 *
202
 * dev          - device number
203
 * buf          - physical address of buffer
204
 * total_count  - total byte count in buffer
205
 * intrflag     - set if this has been called from an interrupt (via DMAbuf_outputintr)
206
 * restart_dma  - set if DMA needs to be re-initialised
207
 *
208
 * Called when:
209
 *  1. Starting output                                  (dmabuf.c:1327)
210
 *  2.                                                  (dmabuf.c:1504)
211
 *  3. A new buffer needs to be sent to the device      (dmabuf.c:1579)
212
 */
213
static void
214
vidc_audio_dma_interrupt (void)
215
{
216
  DMAbuf_outputintr (vidc_adev, 1);
217
}
218
 
219
static void
220
vidc_audio_output_block (int dev, unsigned long buf, int total_count,
221
                         int intrflag, int restart_dma)
222
{
223
  dma_start = (unsigned long)bus_to_virt(buf);
224
  dma_count = total_count;
225
 
226
  if (restart_dma && !intrflag) {
227
    dma_interrupt = vidc_audio_dma_interrupt;
228
    vidc_sound_dma_irq (0, NULL, NULL);
229
    outb (0x30, IOMD_SD0CR);
230
  }
231
}
232
 
233
static void
234
vidc_audio_start_input (int dev, unsigned long buf, int count,
235
                        int intrflag, int restart_dma)
236
{
237
}
238
 
239
static int
240
vidc_audio_prepare_for_input (int dev, int bsize, int bcount)
241
{
242
  return -EINVAL;
243
}
244
 
245
/*
246
 * Prepare for outputting samples to `dev'
247
 *
248
 * Each buffer that will be passed will be `bsize' bytes long,
249
 * with a total of `bcount' buffers.
250
 *
251
 * Called when:
252
 *  1. A trigger enables audio output                   (dmabuf.c:978)
253
 *  2. We get a write buffer without dma_mode setup     (dmabuf.c:1152)
254
 *  3. We restart a transfer                            (dmabuf.c:1324)
255
 */
256
static int
257
vidc_audio_prepare_for_output (int dev, int bsize, int bcount)
258
{
259
  return 0;
260
}
261
 
262
static void
263
vidc_audio_reset (int dev)
264
{
265
}
266
 
267
/*
268
 * Halt a DMA transfer to `dev'
269
 *
270
 * Called when:
271
 *  1. We close the DMAbuf                                      (dmabuf.c:476)
272
 *  2. We run out of output buffers to output to the device.    (dmabuf.c:1456)
273
 *  3. We run out of output buffers and we're closing down.     (dmabuf.c:1546)
274
 *  4. We run out of input buffers in AUTOMODE.                 (dmabuf.c:1651)
275
 */
276
static void
277
vidc_audio_halt_xfer (int dev)
278
{
279
  dma_count = 0;
280
}
281
 
282
static int
283
vidc_audio_local_qlen (int dev)
284
{
285
  return dma_count != 0;
286
}
287
 
288
static struct audio_driver vidc_audio_driver = {
289
  vidc_audio_open,                      /* open                 */
290
  vidc_audio_close,                     /* close                */
291
  vidc_audio_output_block,              /* output_block         */
292
  vidc_audio_start_input,               /* start_input          */
293
  vidc_audio_ioctl,                     /* ioctl                */
294
  vidc_audio_prepare_for_input,         /* prepare_for_input    */
295
  vidc_audio_prepare_for_output,        /* prepare_for_output   */
296
  vidc_audio_reset,                     /* reset                */
297
  vidc_audio_halt_xfer,                 /* halt_xfer            */
298
  vidc_audio_local_qlen,                /*+local_qlen           */
299
  NULL,                                 /*+copy_from_user       */
300
  NULL,                                 /*+halt_input           */
301
  NULL,                                 /*+halt_output          */
302
  NULL,                                 /*+trigger              */
303
  NULL,                                 /*+set_speed            */
304
  NULL,                                 /*+set_bits             */
305
  NULL,                                 /*+set_channels         */
306
};
307
 
308
static struct audio_operations vidc_audio_operations = {
309
  "VIDCsound",
310
  0,
311
  AFMT_U8 | AFMT_S16_LE,
312
  NULL,
313
  &vidc_audio_driver
314
};
315
 
316
void vidc_audio_init (struct address_info *hw_config)
317
{
318
  vidc_audio_volume = 100 | (100 << 8);
319
  if (num_audiodevs < MAX_AUDIO_DEV) {
320
    audio_devs[vidc_adev = num_audiodevs++] = &vidc_audio_operations;
321
    audio_devs[vidc_adev]->dmachan1 = hw_config->dma;
322
    /* size of the total DMA buffer */
323
    audio_devs[vidc_adev]->buffsize = DSP_BUFFSIZE;
324
    audio_devs[vidc_adev]->min_fragment = 10; /* 1024 bytes => 64 buffers */
325
    audio_devs[vidc_adev]->mixer_dev = num_mixers;
326
    audio_devs[vidc_adev]->flags |= 0;
327
  } else
328
    printk ("VIDCsound: Too many PCM devices available\n");
329
}
330
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.