* linux/kernel/chr_drv/sound/audio.c
* Device file manager for /dev/audio
* (C) 1992 Hannu Savolainen (hsavolai@cs.helsinki.fi) See COPYING for further
* details. Should be distributed with this file.
#include "sound_config.h"
#ifdef CONFIGURE_SOUNDCARD
static int wr_buff_no
[MAX_DSP_DEV
]; /* != -1, if there is a
* incomplete output block */
static int wr_buff_size
[MAX_DSP_DEV
], wr_buff_ptr
[MAX_DSP_DEV
];
static char *wr_dma_buf
[MAX_DSP_DEV
];
audio_open (int dev
, struct fileinfo
*file
)
mode
= file
->mode
& O_ACCMODE
;
if ((ret
= DMAbuf_open (dev
, mode
)) < 0)
audio_release (int dev
, struct fileinfo
*file
)
mode
= file
->mode
& O_ACCMODE
;
if (wr_buff_no
[dev
] >= 0)
DMAbuf_start_output (dev
, wr_buff_no
[dev
], wr_buff_ptr
[dev
]);
DMAbuf_release (dev
, mode
);
translate_bytes (const unsigned char *table
, unsigned char *buff
, unsigned long n
)
buff
[i
] = table
[buff
[i
]];
translate_bytes (const void *table
, void *buff
, unsigned long n
)
:"b" ((long) table
), "c" (n
), "D" ((long) buff
), "S" ((long) buff
)
:"bx", "cx", "di", "si", "ax");
audio_write (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
if (!count
) /* Flush output */
if (wr_buff_no
[dev
] >= 0)
DMAbuf_start_output (dev
, wr_buff_no
[dev
], wr_buff_ptr
[dev
]);
{ /* Perform output blocking */
if (wr_buff_no
[dev
] < 0) /* There is no incomplete buffers */
if ((wr_buff_no
[dev
] = DMAbuf_getwrbuffer (dev
, &wr_dma_buf
[dev
], &wr_buff_size
[dev
])) < 0)
if (l
> (wr_buff_size
[dev
] - wr_buff_ptr
[dev
]))
l
= (wr_buff_size
[dev
] - wr_buff_ptr
[dev
]);
COPY_FROM_USER (&wr_dma_buf
[dev
][wr_buff_ptr
[dev
]], buf
, p
, l
);
/* Insert local processing here */
/* This just allows interrupts while the conversion is running */
translate_bytes (ulaw_dsp
, &wr_dma_buf
[dev
][wr_buff_ptr
[dev
]], l
);
if (wr_buff_ptr
[dev
] >= wr_buff_size
[dev
])
if ((err
= DMAbuf_start_output (dev
, wr_buff_no
[dev
], wr_buff_ptr
[dev
])) < 0)
audio_read (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
if ((buff_no
= DMAbuf_getrdbuffer (dev
, &dmabuf
, &l
)) < 0)
/* Insert any local processing here. */
/* This just allows interrupts while the conversion is running */
translate_bytes (dsp_ulaw
, dmabuf
, l
);
COPY_TO_USER (buf
, p
, dmabuf
, l
);
DMAbuf_rmchars (dev
, buff_no
, l
);
audio_ioctl (int dev
, struct fileinfo
*file
,
unsigned int cmd
, unsigned int arg
)
if (wr_buff_no
[dev
] >= 0)
DMAbuf_start_output (dev
, wr_buff_no
[dev
], wr_buff_ptr
[dev
]);
return DMAbuf_ioctl (dev
, cmd
, arg
, 0);
if (wr_buff_no
[dev
] >= 0)
DMAbuf_start_output (dev
, wr_buff_no
[dev
], wr_buff_ptr
[dev
]);
return DMAbuf_ioctl (dev
, cmd
, arg
, 0);
return DMAbuf_ioctl (dev
, cmd
, arg
, 0);
audio_init (long mem_start
)
audio_read (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
audio_write (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
audio_open (int dev
, struct fileinfo
*file
)
return RET_ERROR (ENXIO
);
audio_release (int dev
, struct fileinfo
*file
)
audio_ioctl (int dev
, struct fileinfo
*file
,
unsigned int cmd
, unsigned int arg
)
audio_lseek (int dev
, struct fileinfo
*file
, off_t offset
, int orig
)
audio_init (long mem_start
)