This source file includes following definitions.
- audio_open
 
- audio_release
 
- translate_bytes
 
- translate_bytes
 
- audio_write
 
- audio_read
 
- audio_ioctl
 
- audio_init
 
- audio_read
 
- audio_write
 
- audio_open
 
- audio_release
 
- audio_ioctl
 
- audio_lseek
 
- audio_init
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  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];        
  41 
  42 static int      wr_buff_size[MAX_DSP_DEV], wr_buff_ptr[MAX_DSP_DEV];
  43 
  44 static int      audio_mode[MAX_DSP_DEV];
  45 #define         AM_NONE         0
  46 #define         AM_WRITE        1
  47 #define         AM_READ         2
  48 
  49 static char    *wr_dma_buf[MAX_DSP_DEV];
  50 
  51 int
  52 audio_open (int dev, struct fileinfo *file)
     
  53 {
  54   int             ret;
  55   int             bits;
  56   int             dev_type = dev & 0x0f;
  57   int             mode = file->mode & O_ACCMODE;
  58 
  59   dev = dev >> 4;
  60 
  61   if (dev_type == SND_DEV_DSP16)
  62      bits = 16;
  63   else
  64      bits = 8;
  65 
  66   if ((ret = DMAbuf_open (dev, mode)) < 0)
  67     return ret;
  68 
  69   if (DMAbuf_ioctl (dev, SNDCTL_DSP_SAMPLESIZE, bits, 1) != bits)
  70     {
  71       audio_release (dev, file);
  72       return RET_ERROR (ENXIO);
  73     }
  74 
  75   wr_buff_no[dev] = -1;
  76   audio_mode[dev] = AM_NONE;
  77 
  78   return ret;
  79 }
  80 
  81 void
  82 audio_release (int dev, struct fileinfo *file)
     
  83 {
  84   int             mode;
  85 
  86   dev = dev >> 4;
  87   mode = file->mode & O_ACCMODE;
  88 
  89   if (wr_buff_no[dev] >= 0)
  90     {
  91       DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
  92 
  93       wr_buff_no[dev] = -1;
  94     }
  95 
  96   DMAbuf_release (dev, mode);
  97 }
  98 
  99 #ifdef NO_INLINE_ASM
 100 static void
 101 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
     
 102 {
 103   unsigned long   i;
 104 
 105   for (i = 0; i < n; ++i)
 106     buff[i] = table[buff[i]];
 107 }
 108 
 109 #else
 110 extern inline void
 111 translate_bytes (const void *table, void *buff, unsigned long n)
     
 112 {
 113   __asm__ ("cld\n"
 114            "1:\tlodsb\n\t"
 115            "xlatb\n\t"
 116            "stosb\n\t"
 117            "loop 1b\n\t":
 118            :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
 119            :"bx", "cx", "di", "si", "ax");
 120 }
 121 
 122 #endif
 123 
 124 int
 125 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     
 126 {
 127   int             c, p, l;
 128   int             err;
 129   int             dev_type = dev & 0x0f;
 130 
 131   dev = dev >> 4;
 132 
 133   p = 0;
 134   c = count;
 135 
 136   if (audio_mode[dev] == AM_READ)       
 137   {
 138       wr_buff_no[dev] = -1;
 139   }
 140 
 141   audio_mode[dev] = AM_WRITE;
 142 
 143   if (!count)                   
 144     {
 145       if (wr_buff_no[dev] >= 0)
 146         {
 147           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 148 
 149           wr_buff_no[dev] = -1;
 150         }
 151       return 0;
 152     }
 153 
 154   while (c)
 155     {                           
 156       if (wr_buff_no[dev] < 0)  
 157         {
 158           if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev], &wr_buff_size[dev])) < 0)
 159             return wr_buff_no[dev];
 160           wr_buff_ptr[dev] = 0;
 161         }
 162 
 163       l = c;
 164       if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
 165         l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
 166 
 167       if (!dsp_devs[dev]->copy_from_user)
 168         {                       
 169           COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
 170         }
 171       else
 172         dsp_devs[dev]->copy_from_user (dev,
 173                                wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
 174 
 175 
 176       
 177 
 178       if (dev_type == SND_DEV_AUDIO)
 179       {
 180 #ifdef linux
 181       
 182          __asm__ ("sti");
 183 #endif
 184          translate_bytes (ulaw_dsp, &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
 185       }
 186 
 187       c -= l;
 188       p += l;
 189       wr_buff_ptr[dev] += l;
 190 
 191       if (wr_buff_ptr[dev] >= wr_buff_size[dev])
 192         {
 193           if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
 194             return err;
 195 
 196           wr_buff_no[dev] = -1;
 197         }
 198 
 199     }
 200 
 201   return count;
 202 }
 203 
 204 int
 205 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     
 206 {
 207   int             c, p, l;
 208   char           *dmabuf;
 209   int             buff_no;
 210   int             dev_type = dev & 0x0f;
 211 
 212   dev = dev >> 4;
 213   p = 0;
 214   c = count;
 215 
 216   if (audio_mode[dev] == AM_WRITE)
 217   {
 218       if (wr_buff_no[dev] >= 0)
 219         {
 220           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 221 
 222           wr_buff_no[dev] = -1;
 223         }
 224   }
 225 
 226   audio_mode[dev] = AM_READ;
 227 
 228   while (c)
 229     {
 230       if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
 231         return buff_no;
 232 
 233       if (l > c)
 234         l = c;
 235 
 236       
 237 
 238       if (dev_type == SND_DEV_AUDIO)
 239       {
 240 #ifdef linux
 241         
 242         __asm__ ("sti");
 243 #endif
 244 
 245         translate_bytes (dsp_ulaw, dmabuf, l);
 246       }
 247 
 248       COPY_TO_USER (buf, p, dmabuf, l);
 249 
 250       DMAbuf_rmchars (dev, buff_no, l);
 251 
 252       p += l;
 253       c -= l;
 254     }
 255 
 256   return count - c;
 257 }
 258 
 259 int
 260 audio_ioctl (int dev, struct fileinfo *file,
     
 261              unsigned int cmd, unsigned int arg)
 262 {
 263   int             dev_type = dev & 0x0f;
 264   dev = dev >> 4;
 265 
 266   switch (cmd)
 267     {
 268     case SNDCTL_DSP_SYNC:
 269       if (wr_buff_no[dev] >= 0)
 270         {
 271           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 272 
 273           wr_buff_no[dev] = -1;
 274         }
 275       return DMAbuf_ioctl (dev, cmd, arg, 0);
 276       break;
 277 
 278     case SNDCTL_DSP_POST:
 279       if (wr_buff_no[dev] >= 0)
 280         {
 281           DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
 282 
 283           wr_buff_no[dev] = -1;
 284         }
 285       return 0;
 286       break;
 287 
 288     case SNDCTL_DSP_RESET:
 289       wr_buff_no[dev] = -1;
 290       return DMAbuf_ioctl (dev, cmd, arg, 0);
 291       break;
 292 
 293     default:
 294       if (dev_type == SND_DEV_AUDIO)
 295          return RET_ERROR (EIO);
 296 
 297       return DMAbuf_ioctl (dev, cmd, arg, 0);
 298     }
 299 }
 300 
 301 long
 302 audio_init (long mem_start)
     
 303 {
 304   return mem_start;
 305 }
 306 
 307 #else
 308 
 309 
 310 int
 311 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     
 312 {
 313   return RET_ERROR (EIO);
 314 }
 315 
 316 int
 317 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     
 318 {
 319   return RET_ERROR (EIO);
 320 }
 321 
 322 int
 323 audio_open (int dev, struct fileinfo *file)
     
 324   {
 325     return RET_ERROR (ENXIO);
 326   }
 327 
 328 void
 329 audio_release (int dev, struct fileinfo *file)
     
 330   {
 331   };
 332 int
 333 audio_ioctl (int dev, struct fileinfo *file,
     
 334              unsigned int cmd, unsigned int arg)
 335 {
 336   return RET_ERROR (EIO);
 337 }
 338 
 339 int
 340 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
     
 341 {
 342   return RET_ERROR (EIO);
 343 }
 344 
 345 long
 346 audio_init (long mem_start)
     
 347 {
 348   return mem_start;
 349 }
 350 
 351 #endif
 352 
 353 #endif