178 #include <linux/module.h>
179 #include <linux/slab.h>
180 #include <linux/sound.h>
182 #include <linux/soundcard.h>
183 #include <linux/poll.h>
186 #include <asm/uaccess.h>
190 #define DMASOUND_CORE_REVISION 1
191 #define DMASOUND_CORE_EDITION 6
209 static int sq_unit = -1;
210 static int mixer_unit = -1;
211 static int state_unit = -1;
212 static int irq_installed;
216 static fmode_t shared_resource_owner;
217 static int shared_resources_initialised;
227 static inline void sound_silence(
void)
232 static inline int sound_set_format(
int format)
238 static int sound_set_speed(
int speed)
260 static int sound_set_stereo(
int stereo)
288 ct_func = trans->
ct_s8;
291 ct_func = trans->
ct_u8;
312 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
328 if (!try_module_get(dmasound.
mach.
owner)) {
349 mixer.modify_counter++;
356 memset(&info, 0,
sizeof(info));
360 if (
copy_to_user((
void __user *)arg, &info,
sizeof(info)))
370 static long mixer_unlocked_ioctl(
struct file *file,
u_int cmd,
u_long arg)
375 ret = mixer_ioctl(file, cmd, arg);
385 .unlocked_ioctl = mixer_unlocked_ioctl,
387 .release = mixer_release,
390 static void mixer_init(
void)
412 static void sq_reset_output(
void) ;
414 static int sq_allocate_buffers(
struct sound_queue *sq,
int num,
int size)
425 for (i = 0; i < num; i++) {
438 static void sq_release_buffers(
struct sound_queue *sq)
443 for (i = 0; i < sq->
numBufs; i++)
457 #ifdef DEBUG_DMASOUND
458 printk(
"dmasound_core: tried to sq_setup a locked queue\n") ;
510 #ifdef DEBUG_DMASOUND
521 #ifdef DEBUG_DMASOUND
522 printk(
"dmasound_core: invalid frag count (user set %d)\n", sq->
user_frags) ;
541 static inline void sq_play(
void)
546 static ssize_t sq_write(
struct file *file,
const char __user *
src,
size_t uLeft,
549 ssize_t uWritten = 0;
551 ssize_t uUsed = 0, bUsed, bLeft;
552 unsigned long flags ;
566 if (shared_resources_initialised == 0) {
568 shared_resources_initialised = 1 ;
579 if ((uWritten = sq_setup(&
write_sq)) < 0)
return uWritten ;
605 spin_unlock_irqrestore(&dmasound.
lock, flags);
611 uUsed = sound_copy_translate(dmasound.
trans_write, src, uLeft,
612 dest, &bUsed, bLeft);
617 uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ;
625 return uWritten > 0 ? uWritten : -
EAGAIN;
628 return uWritten > 0 ? uWritten : -
EINTR;
641 uUsed = sound_copy_translate(dmasound.
trans_write, src, uLeft,
642 dest, &bUsed, bLeft);
647 uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ;
657 return uUsed < 0? uUsed: uWritten;
662 unsigned int mask = 0;
666 if ((retVal = sq_setup(&
write_sq)) < 0)
671 poll_wait(file, &
write_sq.action_queue, wait);
679 static inline void sq_init_waitqueue(
struct sound_queue *sq)
688 static inline void sq_wake_up(
struct sound_queue *sq,
struct file *file,
691 if (file->
f_mode & mode) {
703 if (file->
f_mode & mode) {
730 if (( rc = sq_allocate_buffers(sq, numbufs, bufsize))) {
732 sq_wake_up(sq, file, mode);
744 #define write_sq_init_waitqueue() sq_init_waitqueue(&write_sq)
746 #define write_sq_wake_up(file) sq_wake_up(&write_sq, file, FMODE_WRITE)
748 #define write_sq_release_buffers() sq_release_buffers(&write_sq)
749 #define write_sq_open(file) \
750 sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
752 static int sq_open(
struct inode *
inode,
struct file *file)
757 if (!try_module_get(dmasound.
mach.
owner)) {
778 dmasound.
minDev = iminor(inode) & 0x0f;
785 if (shared_resource_owner == 0) {
793 #ifndef DMASOUND_STRICT_OSS_COMPLIANCE
798 sound_set_speed(8000);
811 static void sq_reset_output(
void)
827 static void sq_reset(
void)
835 shared_resources_initialised = 0 ;
838 static int sq_fsync(
struct file *filp,
struct dentry *
dentry)
869 static int sq_release(
struct inode *
inode,
struct file *file)
877 rc = sq_fsync(file, file->
f_path.dentry);
884 if (file->
f_mode & shared_resource_owner) {
885 shared_resource_owner = 0 ;
886 shared_resources_initialised = 0 ;
900 read_sq_wake_up(file);
901 write_sq_wake_up(file);
916 static int shared_resources_are_mine(
fmode_t md)
918 if (shared_resource_owner)
919 return (shared_resource_owner & md) != 0;
921 shared_resource_owner =
md ;
929 static int queues_are_quiescent(
void)
949 #ifdef DEBUG_DMASOUND
950 printk(
"dmasound_core: tried to set_queue_frags on a locked queue\n") ;
978 static int sq_ioctl(
struct file *file,
u_int cmd,
u_long arg)
1028 result = sq_fsync(file, file->
f_path.dentry);
1032 if (file->
f_mode & shared_resource_owner)
1033 shared_resources_initialised = 0 ;
1045 if (shared_resources_are_mine(file->
f_mode)) {
1047 data = sound_set_speed(data) ;
1048 shared_resources_initialised = 0 ;
1059 if (shared_resources_are_mine(file->
f_mode) &&
1060 queues_are_quiescent()) {
1062 shared_resources_initialised = 0 ;
1063 return IOCTL_OUT(arg, sound_set_stereo(data));
1068 if (shared_resources_are_mine(file->
f_mode) &&
1069 queues_are_quiescent()) {
1072 shared_resources_initialised = 0 ;
1073 return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
1078 if (shared_resources_are_mine(file->
f_mode) &&
1079 queues_are_quiescent()) {
1082 shared_resources_initialised = 0 ;
1083 format = sound_set_format(data);
1103 nbufs = (data >> 16) & 0x7fff ;
1104 size = data & 0xffff;
1106 result = set_queue_frags(&
write_sq, nbufs, size) ;
1125 if (
copy_to_user((
void __user *)arg, &info,
sizeof(info)))
1136 return mixer_ioctl(file, cmd, arg);
1141 static long sq_unlocked_ioctl(
struct file *file,
u_int cmd,
u_long arg)
1146 ret = sq_ioctl(file, cmd, arg);
1158 .unlocked_ioctl = sq_unlocked_ioctl,
1160 .release = sq_release,
1163 static int sq_init(
void)
1183 if (shared_resource_owner == 0) {
1187 shared_resources_initialised = 0 ;
1202 #define STAT_BUFF_LEN 768
1209 #define LOW_LEVEL_STAT_ALLOC 162
1219 static char *get_afmt_string(
int afmt)
1229 return "unsigned 8 bit";
1232 return "signed 8 bit";
1235 return "signed 16 bit BE";
1238 return "unsigned 16 bit BE";
1241 return "signed 16 bit LE";
1244 return "unsigned 16 bit LE";
1247 return "format not set" ;
1252 return "ERROR: Unsupported AFMT_XXXX code" ;
1255 static int state_open(
struct inode *inode,
struct file *file)
1267 if (!try_module_get(dmasound.
mach.
owner))
1273 len +=
sprintf(buffer+len,
"%sDMA sound driver rev %03d :\n",
1277 "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1296 len +=
sprintf(buffer+len,
"\t\t === Formats & settings ===\n") ;
1297 len +=
sprintf(buffer+len,
"Parameter %20s%20s\n",
"soft",
"hard") ;
1298 len +=
sprintf(buffer+len,
"Format :%20s%20s\n",
1302 len +=
sprintf(buffer+len,
"Samp Rate:%14d s/sec%14d s/sec\n",
1305 len +=
sprintf(buffer+len,
"Channels :%20s%20s\n",
1311 len +=
sprintf(buffer+len,
"\t\t === Sound Queue status ===\n");
1312 len +=
sprintf(buffer+len,
"Allocated:%8s%6s\n",
"Buffers",
"Size") ;
1313 len +=
sprintf(buffer+len,
"%9s:%8d%6d\n",
1316 "Current : MaxFrg FragSiz MaxAct Frnt Rear "
1317 "Cnt RrSize A B S L xruns\n") ;
1318 len +=
sprintf(buffer+len,
"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1323 #ifdef DEBUG_DMASOUND
1324 printk(
"dmasound: stat buffer used %d bytes\n", len) ;
1337 static int state_release(
struct inode *inode,
struct file *file)
1365 .release = state_release,
1368 static int state_init(
void)
1398 if ((res = sq_init()) < 0)
1402 if ((res = state_init()) < 0)
1409 printk(
KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
1420 "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1423 printk(
KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
1424 numWriteBufs, writeBufSize) ;
1432 if (irq_installed) {
1434 dmasound.
mach.irqcleanup();
1440 if (mixer_unit >= 0)
1442 if (state_unit >= 0)
1450 static int dmasound_setup(
char *
str)
1465 printk(
"dmasound_setup: invalid catch radius, using default = %d\n",
catchRadius);
1471 printk(
"dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
1473 numWriteBufs = ints[1];
1476 if ((size = ints[2]) < 256)
1479 printk(
"dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
1481 writeBufSize =
size;
1485 printk(
"dmasound_setup: invalid number of arguments\n");
1491 __setup(
"dmasound=", dmasound_setup);
1499 #ifdef HAS_8BIT_TABLES
1502 char dmasound_ulaw2dma8[] = {
1503 -126, -122, -118, -114, -110, -106, -102, -98,
1504 -94, -90, -86, -82, -78, -74, -70, -66,
1505 -63, -61, -59, -57, -55, -53, -51, -49,
1506 -47, -45, -43, -41, -39, -37, -35, -33,
1507 -31, -30, -29, -28, -27, -26, -25, -24,
1508 -23, -22, -21, -20, -19, -18, -17, -16,
1509 -16, -15, -15, -14, -14, -13, -13, -12,
1510 -12, -11, -11, -10, -10, -9, -9, -8,
1511 -8, -8, -7, -7, -7, -7, -6, -6,
1512 -6, -6, -5, -5, -5, -5, -4, -4,
1513 -4, -4, -4, -4, -3, -3, -3, -3,
1514 -3, -3, -3, -3, -2, -2, -2, -2,
1515 -2, -2, -2, -2, -2, -2, -2, -2,
1516 -1, -1, -1, -1, -1, -1, -1, -1,
1517 -1, -1, -1, -1, -1, -1, -1, -1,
1518 -1, -1, -1, -1, -1, -1, -1, 0,
1519 125, 121, 117, 113, 109, 105, 101, 97,
1520 93, 89, 85, 81, 77, 73, 69, 65,
1521 62, 60, 58, 56, 54, 52, 50, 48,
1522 46, 44, 42, 40, 38, 36, 34, 32,
1523 30, 29, 28, 27, 26, 25, 24, 23,
1524 22, 21, 20, 19, 18, 17, 16, 15,
1525 15, 14, 14, 13, 13, 12, 12, 11,
1526 11, 10, 10, 9, 9, 8, 8, 7,
1527 7, 7, 6, 6, 6, 6, 5, 5,
1528 5, 5, 4, 4, 4, 4, 3, 3,
1529 3, 3, 3, 3, 2, 2, 2, 2,
1530 2, 2, 2, 2, 1, 1, 1, 1,
1531 1, 1, 1, 1, 1, 1, 1, 1,
1532 0, 0, 0, 0, 0, 0, 0, 0,
1533 0, 0, 0, 0, 0, 0, 0, 0,
1534 0, 0, 0, 0, 0, 0, 0, 0
1539 char dmasound_alaw2dma8[] = {
1540 -22, -21, -24, -23, -18, -17, -20, -19,
1541 -30, -29, -32, -31, -26, -25, -28, -27,
1542 -11, -11, -12, -12, -9, -9, -10, -10,
1543 -15, -15, -16, -16, -13, -13, -14, -14,
1544 -86, -82, -94, -90, -70, -66, -78, -74,
1545 -118, -114, -126, -122, -102, -98, -110, -106,
1546 -43, -41, -47, -45, -35, -33, -39, -37,
1547 -59, -57, -63, -61, -51, -49, -55, -53,
1548 -2, -2, -2, -2, -2, -2, -2, -2,
1549 -2, -2, -2, -2, -2, -2, -2, -2,
1550 -1, -1, -1, -1, -1, -1, -1, -1,
1551 -1, -1, -1, -1, -1, -1, -1, -1,
1552 -6, -6, -6, -6, -5, -5, -5, -5,
1553 -8, -8, -8, -8, -7, -7, -7, -7,
1554 -3, -3, -3, -3, -3, -3, -3, -3,
1555 -4, -4, -4, -4, -4, -4, -4, -4,
1556 21, 20, 23, 22, 17, 16, 19, 18,
1557 29, 28, 31, 30, 25, 24, 27, 26,
1558 10, 10, 11, 11, 8, 8, 9, 9,
1559 14, 14, 15, 15, 12, 12, 13, 13,
1560 86, 82, 94, 90, 70, 66, 78, 74,
1561 118, 114, 126, 122, 102, 98, 110, 106,
1562 43, 41, 47, 45, 35, 33, 39, 37,
1563 59, 57, 63, 61, 51, 49, 55, 53,
1564 1, 1, 1, 1, 1, 1, 1, 1,
1565 1, 1, 1, 1, 1, 1, 1, 1,
1566 0, 0, 0, 0, 0, 0, 0, 0,
1567 0, 0, 0, 0, 0, 0, 0, 0,
1568 5, 5, 5, 5, 4, 4, 4, 4,
1569 7, 7, 7, 7, 6, 6, 6, 6,
1570 2, 2, 2, 2, 2, 2, 2, 2,
1571 3, 3, 3, 3, 3, 3, 3, 3
1586 #ifdef HAS_8BIT_TABLES