root/drivers/sound/dsp.c

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

DEFINITIONS

This source file includes following definitions.
  1. dsp_open
  2. dsp_release
  3. dsp_write
  4. dsp_read
  5. dsp_ioctl
  6. dsp_init
  7. dsp_read
  8. dsp_write
  9. dsp_open
  10. dsp_release
  11. dsp_ioctl
  12. dsp_lseek
  13. dsp_init

   1 /*
   2  * linux/kernel/chr_drv/sound/dsp.c
   3  * 
   4  * Device file manager for /dev/dsp
   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 
  34 #ifndef EXCLUDE_AUDIO
  35 
  36 #define ON              1
  37 #define OFF             0
  38 
  39 static int      wr_buff_no[MAX_DSP_DEV];        /* != -1, if there is a
  40                                                  * incomplete output block */
  41 static int      wr_buff_size[MAX_DSP_DEV], wr_buf_ptr[MAX_DSP_DEV];
  42 static char    *wr_dma_buf[MAX_DSP_DEV];
  43 
  44 int
  45 dsp_open (int dev, struct fileinfo *file, int bits)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47   int             mode;
  48   int             ret;
  49 
  50   dev = dev >> 4;
  51   mode = file->mode & O_ACCMODE;
  52 
  53   if ((ret = DMAbuf_open (dev, mode)) < 0)
  54     return ret;
  55 
  56   if (DMAbuf_ioctl (dev, SNDCTL_DSP_SAMPLESIZE, bits, 1) != bits)
  57     {
  58       dsp_release (dev, file);
  59       return RET_ERROR (ENXIO);
  60     }
  61 
  62   wr_buff_no[dev] = -1;
  63 
  64   return ret;
  65 }
  66 
  67 void
  68 dsp_release (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70   int             mode;
  71 
  72   dev = dev >> 4;
  73   mode = file->mode & O_ACCMODE;
  74 
  75   if (wr_buff_no[dev] >= 0)
  76     {
  77       DMAbuf_start_output (dev, wr_buff_no[dev], wr_buf_ptr[dev]);
  78 
  79       wr_buff_no[dev] = -1;
  80     }
  81 
  82   DMAbuf_release (dev, mode);
  83 }
  84 
  85 
  86 int
  87 dsp_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89   int             c, p, l;
  90   int             err;
  91 
  92   dev = dev >> 4;
  93 
  94   p = 0;
  95   c = count;
  96 
  97   if (!count)                   /* Flush output */
  98     {
  99       if (wr_buff_no[dev] >= 0)
 100         {
 101           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buf_ptr[dev]);
 102 
 103           wr_buff_no[dev] = -1;
 104         }
 105       return 0;
 106     }
 107 
 108   while (c)
 109     {                           /* Perform output blocking */
 110       if (wr_buff_no[dev] < 0)  /* There is no incomplete buffers */
 111         {
 112           if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev],
 113                                                    &wr_buff_size[dev])) < 0)
 114             return wr_buff_no[dev];
 115           wr_buf_ptr[dev] = 0;
 116         }
 117 
 118       l = c;
 119       if (l > (wr_buff_size[dev] - wr_buf_ptr[dev]))
 120         l = (wr_buff_size[dev] - wr_buf_ptr[dev]);
 121 
 122       if (!dsp_devs[dev]->copy_from_user)
 123         {                       /* No device specific copy routine */
 124           COPY_FROM_USER (&wr_dma_buf[dev][wr_buf_ptr[dev]], buf, p, l);
 125         }
 126       else
 127         dsp_devs[dev]->copy_from_user (dev,
 128                                wr_dma_buf[dev], wr_buf_ptr[dev], buf, p, l);
 129 
 130       c -= l;
 131       p += l;
 132       wr_buf_ptr[dev] += l;
 133 
 134       if (wr_buf_ptr[dev] >= wr_buff_size[dev])
 135         {
 136           if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buf_ptr[dev])) < 0)
 137             return err;
 138 
 139           wr_buff_no[dev] = -1;
 140         }
 141 
 142     }
 143 
 144   return count;
 145 }
 146 
 147 
 148 int
 149 dsp_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   int             c, p, l;
 152   char           *dmabuf;
 153   int             buff_no;
 154 
 155   dev = dev >> 4;
 156   p = 0;
 157   c = count;
 158 
 159   while (c)
 160     {
 161       if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
 162         return buff_no;
 163 
 164       if (l > c)
 165         l = c;
 166 
 167       /* Insert any local processing here. */
 168 
 169       COPY_TO_USER (buf, 0, dmabuf, l);
 170 
 171       DMAbuf_rmchars (dev, buff_no, l);
 172 
 173       p += l;
 174       c -= l;
 175     }
 176 
 177   return count - c;
 178 }
 179 
 180 int
 181 dsp_ioctl (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 182            unsigned int cmd, unsigned int arg)
 183 {
 184 
 185   dev = dev >> 4;
 186 
 187   switch (cmd)
 188     {
 189     case SNDCTL_DSP_SYNC:
 190       if (wr_buff_no[dev] >= 0)
 191         {
 192           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buf_ptr[dev]);
 193 
 194           wr_buff_no[dev] = -1;
 195         }
 196       return DMAbuf_ioctl (dev, cmd, arg, 0);
 197       break;
 198 
 199     case SNDCTL_DSP_POST:
 200       if (wr_buff_no[dev] >= 0)
 201         {
 202           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buf_ptr[dev]);
 203 
 204           wr_buff_no[dev] = -1;
 205         }
 206       return 0;
 207       break;
 208 
 209     case SNDCTL_DSP_RESET:
 210       wr_buff_no[dev] = -1;
 211       return DMAbuf_ioctl (dev, cmd, arg, 0);
 212       break;
 213 
 214     default:
 215       return DMAbuf_ioctl (dev, cmd, arg, 0);
 216     }
 217 }
 218 
 219 long
 220 dsp_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222   return mem_start;
 223 }
 224 
 225 #else
 226 /* Stub version */
 227 int
 228 dsp_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 229 {
 230   return RET_ERROR (EIO);
 231 }
 232 
 233 int
 234 dsp_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {
 236   return RET_ERROR (EIO);
 237 }
 238 
 239 int
 240 dsp_open (int dev, struct fileinfo *file, int bits)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242   return RET_ERROR (ENXIO);
 243 }
 244 
 245 void
 246 dsp_release (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 247   {
 248   };
 249 int
 250 dsp_ioctl (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 251            unsigned int cmd, unsigned int arg)
 252 {
 253   return RET_ERROR (EIO);
 254 }
 255 
 256 int
 257 dsp_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 258 {
 259   return RET_ERROR (EIO);
 260 }
 261 
 262 long
 263 dsp_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265   return mem_start;
 266 }
 267 
 268 #endif
 269 
 270 #endif

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