root/drivers/sound/audio.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. audio_open
  2. audio_release
  3. translate_bytes
  4. translate_bytes
  5. audio_write
  6. audio_read
  7. audio_ioctl
  8. audio_init
  9. audio_read
  10. audio_write
  11. audio_open
  12. audio_release
  13. audio_ioctl
  14. audio_lseek
  15. audio_init

   1 /*
   2  * linux/kernel/chr_drv/sound/audio.c
   3  * 
   4  * Device file manager for /dev/audio
   5  * 
   6  * Copyright by Hannu Savolainen 1993
   7  * 
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  * 
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  * 
  28  */
  29 
  30 #include "sound_config.h"
  31 
  32 #ifdef CONFIGURE_SOUNDCARD
  33 #ifndef EXCLUDE_AUDIO
  34 
  35 #include "ulaw.h"
  36 
  37 #define ON              1
  38 #define OFF             0
  39 
  40 static int      wr_buff_no[MAX_DSP_DEV];        /* != -1, if there is a
  41                                                  * incomplete output block */
  42 static int      wr_buff_size[MAX_DSP_DEV], wr_buff_ptr[MAX_DSP_DEV];
  43 static char    *wr_dma_buf[MAX_DSP_DEV];
  44 
  45 int
  46 audio_open (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   int             mode;
  49   int             ret;
  50 
  51   dev = dev >> 4;
  52   mode = file->mode & O_ACCMODE;
  53 
  54   if ((ret = DMAbuf_open (dev, mode)) < 0)
  55     return ret;
  56 
  57   wr_buff_no[dev] = -1;
  58   return ret;
  59 }
  60 
  61 void
  62 audio_release (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64   int             mode;
  65 
  66   dev = dev >> 4;
  67   mode = file->mode & O_ACCMODE;
  68 
  69   if (wr_buff_no[dev] >= 0)
  70     {
  71       DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
  72 
  73       wr_buff_no[dev] = -1;
  74     }
  75 
  76   DMAbuf_release (dev, mode);
  77 }
  78 
  79 #ifdef NO_INLINE_ASM
  80 static void
  81 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83   unsigned long   i;
  84 
  85   for (i = 0; i < n; ++i)
  86     buff[i] = table[buff[i]];
  87 }
  88 
  89 #else
  90 extern inline void
  91 translate_bytes (const void *table, void *buff, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   __asm__ ("cld\n"
  94            "1:\tlodsb\n\t"
  95            "xlatb\n\t"
  96            "stosb\n\t"
  97            "loop 1b\n\t":
  98            :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
  99            :"bx", "cx", "di", "si", "ax");
 100 }
 101 
 102 #endif
 103 
 104 int
 105 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107   int             c, p, l;
 108   int             err;
 109 
 110   dev = dev >> 4;
 111 
 112   p = 0;
 113   c = count;
 114 
 115   if (!count)                   /* Flush output */
 116     {
 117       if (wr_buff_no[dev] >= 0)
 118         {
 119           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 120 
 121           wr_buff_no[dev] = -1;
 122         }
 123       return 0;
 124     }
 125 
 126   while (c)
 127     {                           /* Perform output blocking */
 128       if (wr_buff_no[dev] < 0)  /* There is no incomplete buffers */
 129         {
 130           if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev], &wr_buff_size[dev])) < 0)
 131             return wr_buff_no[dev];
 132           wr_buff_ptr[dev] = 0;
 133         }
 134 
 135       l = c;
 136       if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
 137         l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
 138 
 139       COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
 140 
 141       /* Insert local processing here */
 142 
 143 #ifdef linux
 144       /* This just allows interrupts while the conversion is running */
 145       __asm__ ("sti");
 146 #endif
 147       translate_bytes (ulaw_dsp, &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
 148 
 149       c -= l;
 150       p += l;
 151       wr_buff_ptr[dev] += l;
 152 
 153       if (wr_buff_ptr[dev] >= wr_buff_size[dev])
 154         {
 155           if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
 156             return err;
 157 
 158           wr_buff_no[dev] = -1;
 159         }
 160 
 161     }
 162 
 163   return count;
 164 }
 165 
 166 int
 167 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169   int             c, p, l;
 170   char           *dmabuf;
 171   int             buff_no;
 172 
 173   dev = dev >> 4;
 174   p = 0;
 175   c = count;
 176 
 177   while (c)
 178     {
 179       if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
 180         return buff_no;
 181 
 182       if (l > c)
 183         l = c;
 184 
 185       /* Insert any local processing here. */
 186 #ifdef linux
 187       /* This just allows interrupts while the conversion is running */
 188       __asm__ ("sti");
 189 #endif
 190 
 191       translate_bytes (dsp_ulaw, dmabuf, l);
 192 
 193       COPY_TO_USER (buf, p, dmabuf, l);
 194 
 195       DMAbuf_rmchars (dev, buff_no, l);
 196 
 197       p += l;
 198       c -= l;
 199     }
 200 
 201   return count - c;
 202 }
 203 
 204 int
 205 audio_ioctl (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 206              unsigned int cmd, unsigned int arg)
 207 {
 208   dev = dev >> 4;
 209 
 210   switch (cmd)
 211     {
 212     case SNDCTL_DSP_SYNC:
 213       if (wr_buff_no[dev] >= 0)
 214         {
 215           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 216 
 217           wr_buff_no[dev] = -1;
 218         }
 219       return DMAbuf_ioctl (dev, cmd, arg, 0);
 220       break;
 221 
 222     case SNDCTL_DSP_POST:
 223       if (wr_buff_no[dev] >= 0)
 224         {
 225           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 226 
 227           wr_buff_no[dev] = -1;
 228         }
 229       return 0;
 230       break;
 231 
 232     case SNDCTL_DSP_RESET:
 233       wr_buff_no[dev] = -1;
 234       return DMAbuf_ioctl (dev, cmd, arg, 0);
 235       break;
 236 
 237     default:
 238 #if 1
 239       return RET_ERROR (EIO);
 240 #else
 241       return DMAbuf_ioctl (dev, cmd, arg, 0);
 242 #endif
 243     }
 244 }
 245 
 246 long
 247 audio_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249   return mem_start;
 250 }
 251 
 252 #else
 253 /* Stub versions */
 254 
 255 int
 256 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 257 {
 258   return RET_ERROR (EIO);
 259 }
 260 
 261 int
 262 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264   return RET_ERROR (EIO);
 265 }
 266 
 267 int
 268 audio_open (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 269   {
 270     return RET_ERROR (ENXIO);
 271   }
 272 
 273 void
 274 audio_release (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 275   {
 276   };
 277 int
 278 audio_ioctl (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 279              unsigned int cmd, unsigned int arg)
 280 {
 281   return RET_ERROR (EIO);
 282 }
 283 
 284 int
 285 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287   return RET_ERROR (EIO);
 288 }
 289 
 290 long
 291 audio_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 292 {
 293   return mem_start;
 294 }
 295 
 296 #endif
 297 
 298 #endif

/* [previous][next][first][last][top][bottom][index][help] */