17 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/soundcard.h>
23 #include <asm/uaccess.h>
29 #define DMASOUND_Q40_REVISION 0
30 #define DMASOUND_Q40_EDITION 3
32 static int expand_bal;
33 static int expand_data;
40 static void Q40Free(
void *,
unsigned int);
41 static int Q40IrqInit(
void);
43 static void Q40IrqCleanUp(
void);
45 static void Q40Silence(
void);
46 static void Q40Init(
void);
47 static int Q40SetFormat(
int format);
48 static int Q40SetVolume(
int volume);
49 static void Q40PlayNextFrame(
int index);
50 static void Q40Play(
void);
53 static void Q40Interrupt(
void);
61 static ssize_t q40_ct_law(
const u_char __user *userPtr,
size_t userCount,
69 used = count =
min_t(
size_t, userCount, frameLeft);
82 static ssize_t q40_ct_s8(
const u_char __user *userPtr,
size_t userCount,
89 used = count =
min_t(
size_t, userCount, frameLeft);
101 static ssize_t q40_ct_u8(
const u_char __user *userPtr,
size_t userCount,
108 used = count =
min_t(
size_t, userCount, frameLeft);
117 static ssize_t q40_ctx_law(
const u_char __user *userPtr,
size_t userCount,
121 unsigned char *table = (
unsigned char *)
123 unsigned int data = expand_data;
125 int bal = expand_bal;
149 *frameUsed += (ftotal - frameLeft);
155 static ssize_t q40_ctx_s8(
const u_char __user *userPtr,
size_t userCount,
160 unsigned int data = expand_data;
161 int bal = expand_bal;
186 *frameUsed += (ftotal - frameLeft);
192 static ssize_t q40_ctx_u8(
const u_char __user *userPtr,
size_t userCount,
197 unsigned int data = expand_data;
198 int bal = expand_bal;
221 *frameUsed += (ftotal - frameLeft) ;
227 static ssize_t q40_ctc_law(
const u_char __user *userPtr,
size_t userCount,
231 unsigned char *table = (
unsigned char *)
233 unsigned int data = expand_data;
235 int bal = expand_bal;
246 if (!(bal<(-hSpeed))) {
249 data = 0x80 + table[
c];
262 *frameUsed += (ftotal - frameLeft);
268 static ssize_t q40_ctc_s8(
const u_char __user *userPtr,
size_t userCount,
273 unsigned int data = expand_data;
274 int bal = expand_bal;
285 if (!(bal<(-hSpeed))) {
301 *frameUsed += (ftotal - frameLeft);
307 static ssize_t q40_ctc_u8(
const u_char __user *userPtr,
size_t userCount,
312 unsigned int data = expand_data;
313 int bal = expand_bal;
324 if (!(bal<(-hSpeed))) {
340 *frameUsed += (ftotal - frameLeft) ;
346 static TRANS transQ40Normal = {
347 q40_ct_law, q40_ct_law, q40_ct_s8, q40_ct_u8,
NULL,
NULL,
NULL, NULL
350 static TRANS transQ40Expanding = {
351 q40_ctx_law, q40_ctx_law, q40_ctx_s8, q40_ctx_u8,
NULL,
NULL,
NULL, NULL
354 static TRANS transQ40Compressing = {
355 q40_ctc_law, q40_ctc_law, q40_ctc_s8, q40_ctc_u8,
NULL,
NULL,
NULL, NULL
366 static void Q40Free(
void *
ptr,
unsigned int size)
371 static int __init Q40IrqInit(
void)
375 "DMA sound", Q40Interrupt))
383 static void Q40IrqCleanUp(
void)
391 static void Q40Silence(
void)
398 static unsigned int q40_sc;
400 static void Q40PlayNextFrame(
int index)
419 speed=(
dmasound.hard.speed==10000 ? 0 : 1);
425 "Q40 sound", Q40Interrupt);
428 "Q40 sound", Q40Interrupt);
429 if (error && printk_ratelimit())
430 pr_err(
"Couldn't register sound interrupt\n");
437 static void Q40Play(
void)
455 spin_unlock_irqrestore(&
dmasound.lock, flags);
466 }
else Q40Interrupt();
470 static irqreturn_t Q40MonoInterrupt(
int irq,
void *dummy)
478 }
else Q40Interrupt();
482 static void Q40Interrupt(
void)
507 static void Q40Init(
void)
510 const int freq[] = {10000, 20000};
515 for (i = 0; i < 2; i++)
525 dmasound.trans_write = &transQ40Normal;
527 dmasound.trans_write = &transQ40Expanding;
534 dmasound.trans_write = &transQ40Compressing;
535 }
else if (
dmasound.hard.speed > 10000) {
544 static int Q40SetFormat(
int format)
571 static int Q40SetVolume(
int volume)
597 .dma_alloc = Q40Alloc,
599 .irqinit = Q40IrqInit,
601 .irqcleanup = Q40IrqCleanUp,
604 .silence = Q40Silence,
605 .setFormat = Q40SetFormat,
606 .setVolume = Q40SetVolume,
608 .min_dsp_speed = 10000,
618 static int __init dmasound_q40_init(
void)
622 dmasound.mach.default_hard = def_hard ;
623 dmasound.mach.default_soft = def_soft ;
629 static void __exit dmasound_q40_cleanup(
void)