Release 4.7 sound/oss/dmasound/dmasound_q40.c
/*
* linux/sound/oss/dmasound/dmasound_q40.c
*
* Q40 DMA Sound Driver
*
* See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
* prior to 28/01/2001
*
* 28/01/2001 [0.1] Iain Sandoe
* - added versioning
* - put in and populated the hardware_afmts field.
* [0.2] - put in SNDCTL_DSP_GETCAPS value.
* [0.3] - put in default hard/soft settings.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/soundcard.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/q40ints.h>
#include <asm/q40_master.h>
#include "dmasound.h"
#define DMASOUND_Q40_REVISION 0
#define DMASOUND_Q40_EDITION 3
static int expand_bal;
/* Balance factor for expanding (not volume!) */
static int expand_data;
/* Data for expanding */
/*** Low level stuff *********************************************************/
static void *Q40Alloc(unsigned int size, gfp_t flags);
static void Q40Free(void *, unsigned int);
static int Q40IrqInit(void);
#ifdef MODULE
static void Q40IrqCleanUp(void);
#endif
static void Q40Silence(void);
static void Q40Init(void);
static int Q40SetFormat(int format);
static int Q40SetVolume(int volume);
static void Q40PlayNextFrame(int index);
static void Q40Play(void);
static irqreturn_t Q40StereoInterrupt(int irq, void *dummy);
static irqreturn_t Q40MonoInterrupt(int irq, void *dummy);
static void Q40Interrupt(void);
/*** Mid level stuff *********************************************************/
/* userCount, frameUsed, frameLeft == byte counts */
static ssize_t q40_ct_law(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8;
ssize_t count, used;
u_char *p = (u_char *) &frame[*frameUsed];
used = count = min_t(size_t, userCount, frameLeft);
if (copy_from_user(p,userPtr,count))
return -EFAULT;
while (count > 0) {
*p = table[*p]+128;
p++;
count--;
}
*frameUsed += used ;
return used;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 117 | 95.12% | 1 | 25.00% |
linus torvalds | linus torvalds | 5 | 4.07% | 2 | 50.00% |
al viro | al viro | 1 | 0.81% | 1 | 25.00% |
| Total | 123 | 100.00% | 4 | 100.00% |
static ssize_t q40_ct_s8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
ssize_t count, used;
u_char *p = (u_char *) &frame[*frameUsed];
used = count = min_t(size_t, userCount, frameLeft);
if (copy_from_user(p,userPtr,count))
return -EFAULT;
while (count > 0) {
*p = *p + 128;
p++;
count--;
}
*frameUsed += used;
return used;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 85 | 81.73% | 1 | 20.00% |
dave jones | dave jones | 13 | 12.50% | 1 | 20.00% |
linus torvalds | linus torvalds | 5 | 4.81% | 2 | 40.00% |
al viro | al viro | 1 | 0.96% | 1 | 20.00% |
| Total | 104 | 100.00% | 5 | 100.00% |
static ssize_t q40_ct_u8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
ssize_t count, used;
u_char *p = (u_char *) &frame[*frameUsed];
used = count = min_t(size_t, userCount, frameLeft);
if (copy_from_user(p,userPtr,count))
return -EFAULT;
*frameUsed += used;
return used;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 75 | 91.46% | 1 | 20.00% |
linus torvalds | linus torvalds | 5 | 6.10% | 2 | 40.00% |
dave jones | dave jones | 1 | 1.22% | 1 | 20.00% |
al viro | al viro | 1 | 1.22% | 1 | 20.00% |
| Total | 82 | 100.00% | 5 | 100.00% |
/* a bit too complicated to optimise right now ..*/
static ssize_t q40_ctx_law(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
unsigned char *table = (unsigned char *)
(dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
unsigned int data = expand_data;
u_char *p = (u_char *) &frame[*frameUsed];
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
if (bal < 0) {
if (userCount == 0)
break;
if (get_user(c, userPtr++))
return -EFAULT;
data = table[c];
data += 0x80;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft);
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave jones | dave jones | 106 | 53.27% | 1 | 25.00% |
pre-git | pre-git | 91 | 45.73% | 1 | 25.00% |
linus torvalds | linus torvalds | 1 | 0.50% | 1 | 25.00% |
al viro | al viro | 1 | 0.50% | 1 | 25.00% |
| Total | 199 | 100.00% | 4 | 100.00% |
static ssize_t q40_ctx_s8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
u_char *p = (u_char *) &frame[*frameUsed];
unsigned int data = expand_data;
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
if (bal < 0) {
if (userCount == 0)
break;
if (get_user(c, userPtr++))
return -EFAULT;
data = c ;
data += 0x80;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft);
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave jones | dave jones | 111 | 64.53% | 1 | 25.00% |
pre-git | pre-git | 59 | 34.30% | 1 | 25.00% |
linus torvalds | linus torvalds | 1 | 0.58% | 1 | 25.00% |
al viro | al viro | 1 | 0.58% | 1 | 25.00% |
| Total | 172 | 100.00% | 4 | 100.00% |
static ssize_t q40_ctx_u8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
u_char *p = (u_char *) &frame[*frameUsed];
unsigned int data = expand_data;
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
if (bal < 0) {
if (userCount == 0)
break;
if (get_user(c, userPtr++))
return -EFAULT;
data = c ;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft) ;
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 86 | 51.19% | 1 | 33.33% |
dave jones | dave jones | 81 | 48.21% | 1 | 33.33% |
al viro | al viro | 1 | 0.60% | 1 | 33.33% |
| Total | 168 | 100.00% | 3 | 100.00% |
/* compressing versions */
static ssize_t q40_ctc_law(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
unsigned char *table = (unsigned char *)
(dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
unsigned int data = expand_data;
u_char *p = (u_char *) &frame[*frameUsed];
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
while(bal<0) {
if (userCount == 0)
goto lout;
if (!(bal<(-hSpeed))) {
if (get_user(c, userPtr))
return -EFAULT;
data = 0x80 + table[c];
}
userPtr++;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
lout:
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft);
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 191 | 88.02% | 1 | 33.33% |
dave jones | dave jones | 25 | 11.52% | 1 | 33.33% |
al viro | al viro | 1 | 0.46% | 1 | 33.33% |
| Total | 217 | 100.00% | 3 | 100.00% |
static ssize_t q40_ctc_s8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
u_char *p = (u_char *) &frame[*frameUsed];
unsigned int data = expand_data;
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
while (bal < 0) {
if (userCount == 0)
goto lout;
if (!(bal<(-hSpeed))) {
if (get_user(c, userPtr))
return -EFAULT;
data = c + 0x80;
}
userPtr++;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
lout:
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft);
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 164 | 86.32% | 1 | 33.33% |
dave jones | dave jones | 25 | 13.16% | 1 | 33.33% |
al viro | al viro | 1 | 0.53% | 1 | 33.33% |
| Total | 190 | 100.00% | 3 | 100.00% |
static ssize_t q40_ctc_u8(const u_char __user *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
u_char *p = (u_char *) &frame[*frameUsed];
unsigned int data = expand_data;
int bal = expand_bal;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char c;
while (bal < 0) {
if (userCount == 0)
goto lout;
if (!(bal<(-hSpeed))) {
if (get_user(c, userPtr))
return -EFAULT;
data = c ;
}
userPtr++;
userCount--;
bal += hSpeed;
}
*p++ = data;
frameLeft--;
bal -= sSpeed;
}
lout:
expand_bal = bal;
expand_data = data;
*frameUsed += (ftotal - frameLeft) ;
utotal -= userCount;
return utotal;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 163 | 86.70% | 1 | 33.33% |
dave jones | dave jones | 24 | 12.77% | 1 | 33.33% |
al viro | al viro | 1 | 0.53% | 1 | 33.33% |
| Total | 188 | 100.00% | 3 | 100.00% |
static TRANS transQ40Normal = {
q40_ct_law, q40_ct_law, q40_ct_s8, q40_ct_u8, NULL, NULL, NULL, NULL
};
static TRANS transQ40Expanding = {
q40_ctx_law, q40_ctx_law, q40_ctx_s8, q40_ctx_u8, NULL, NULL, NULL, NULL
};
static TRANS transQ40Compressing = {
q40_ctc_law, q40_ctc_law, q40_ctc_s8, q40_ctc_u8, NULL, NULL, NULL, NULL
};
/*** Low level stuff *********************************************************/
static void *Q40Alloc(unsigned int size, gfp_t flags)
{
return kmalloc(size, flags); /* change to vmalloc */
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 22 | 95.65% | 1 | 50.00% |
al viro | al viro | 1 | 4.35% | 1 | 50.00% |
| Total | 23 | 100.00% | 2 | 100.00% |
static void Q40Free(void *ptr, unsigned int size)
{
kfree(ptr);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 19 | 100.00% | 1 | 100.00% |
| Total | 19 | 100.00% | 1 | 100.00% |
static int __init Q40IrqInit(void)
{
/* Register interrupt handler. */
if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
"DMA sound", Q40Interrupt))
return 0;
return(1);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 27 | 81.82% | 1 | 50.00% |
geert uytterhoeven | geert uytterhoeven | 6 | 18.18% | 1 | 50.00% |
| Total | 33 | 100.00% | 2 | 100.00% |
#ifdef MODULE
static void Q40IrqCleanUp(void)
{
master_outb(0,SAMPLE_ENABLE_REG);
free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 22 | 100.00% | 1 | 100.00% |
| Total | 22 | 100.00% | 1 | 100.00% |
#endif /* MODULE */
static void Q40Silence(void)
{
master_outb(0,SAMPLE_ENABLE_REG);
*DAC_LEFT=*DAC_RIGHT=127;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 22 | 95.65% | 1 | 50.00% |
dave jones | dave jones | 1 | 4.35% | 1 | 50.00% |
| Total | 23 | 100.00% | 2 | 100.00% |
static char *q40_pp;
static unsigned int q40_sc;
static void Q40PlayNextFrame(int index)
{
u_char *start;
u_long size;
u_char speed;
int error;
/* used by Q40Play() if all doubts whether there really is something
* to be played are already wiped out.
*/
start = write_sq.buffers[write_sq.front];
size = (write_sq.count == index ? write_sq.rear_size : write_sq.block_size);
q40_pp=start;
q40_sc=size;
write_sq.front = (write_sq.front+1) % write_sq.max_count;
write_sq.active++;
speed=(dmasound.hard.speed==10000 ? 0 : 1);
master_outb( 0,SAMPLE_ENABLE_REG);
free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
if (dmasound.soft.stereo)
error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
"Q40 sound", Q40Interrupt);
else
error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
"Q40 sound", Q40Interrupt);
if (error && printk_ratelimit())
pr_err("Couldn't register sound interrupt\n");
master_outb( speed, SAMPLE_RATE_REG);
master_outb( 1,SAMPLE_CLEAR_REG);
master_outb( 1,SAMPLE_ENABLE_REG);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 164 | 89.62% | 1 | 50.00% |
geert uytterhoeven | geert uytterhoeven | 19 | 10.38% | 1 | 50.00% |
| Total | 183 | 100.00% | 2 | 100.00% |
static void Q40Play(void)
{
unsigned long flags;
if (write_sq.active || write_sq.count<=0 ) {
/* There's already a frame loaded */
return;
}
/* nothing in the queue */
if (write_sq.count <= 1 && write_sq.rear_size < write_sq.block_size && !write_sq.syncing) {
/* hmmm, the only existing frame is not
* yet filled and we're not syncing?
*/
return;
}
spin_lock_irqsave(&dmasound.lock, flags);
Q40PlayNextFrame(1);
spin_unlock_irqrestore(&dmasound.lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 67 | 84.81% | 1 | 33.33% |
peter waechtler | peter waechtler | 11 | 13.92% | 1 | 33.33% |
geert uytterhoeven | geert uytterhoeven | 1 | 1.27% | 1 | 33.33% |
| Total | 79 | 100.00% | 3 | 100.00% |
static irqreturn_t Q40StereoInterrupt(int irq, void *dummy)
{
spin_lock(&dmasound.lock);
if (q40_sc>1){
*DAC_LEFT=*q40_pp++;
*DAC_RIGHT=*q40_pp++;
q40_sc -=2;
master_outb(1,SAMPLE_CLEAR_REG);
}else Q40Interrupt();
spin_unlock(&dmasound.lock);
return IRQ_HANDLED;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 49 | 71.01% | 1 | 33.33% |
peter waechtler | peter waechtler | 16 | 23.19% | 1 | 33.33% |
andrew morton | andrew morton | 4 | 5.80% | 1 | 33.33% |
| Total | 69 | 100.00% | 3 | 100.00% |
static irqreturn_t Q40MonoInterrupt(int irq, void *dummy)
{
spin_lock(&dmasound.lock);
if (q40_sc>0){
*DAC_LEFT=*q40_pp;
*DAC_RIGHT=*q40_pp++;
q40_sc --;
master_outb(1,SAMPLE_CLEAR_REG);
}else Q40Interrupt();
spin_unlock(&dmasound.lock);
return IRQ_HANDLED;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 47 | 70.15% | 1 | 33.33% |
peter waechtler | peter waechtler | 16 | 23.88% | 1 | 33.33% |
andrew morton | andrew morton | 4 | 5.97% | 1 | 33.33% |
| Total | 67 | 100.00% | 3 | 100.00% |
static void Q40Interrupt(void)
{
if (!write_sq.active) {
/* playing was interrupted and sq_reset() has already cleared
* the sq variables, so better don't do anything here.
*/
WAKE_UP(write_sq.sync_queue);
master_outb(0,SAMPLE_ENABLE_REG); /* better safe */
goto exit;
} else write_sq.active=0;
write_sq.count--;
Q40Play();
if (q40_sc<2)
{ /* there was nothing to play, disable irq */
master_outb(0,SAMPLE_ENABLE_REG);
*DAC_LEFT=*DAC_RIGHT=127;
}
WAKE_UP(write_sq.action_queue);
exit:
master_outb(1,SAMPLE_CLEAR_REG);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 90 | 98.90% | 1 | 50.00% |
dave jones | dave jones | 1 | 1.10% | 1 | 50.00% |
| Total | 91 | 100.00% | 2 | 100.00% |
static void Q40Init(void)
{
int i, idx;
const int freq[] = {10000, 20000};
/* search a frequency that fits into the allowed error range */
idx = -1;
for (i = 0; i < 2; i++)
if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) <= catchRadius)
idx = i;
dmasound.hard = dmasound.soft;
/*sound.hard.stereo=1;*/ /* no longer true */
dmasound.hard.size=8;
if (idx > -1) {
dmasound.soft.speed = freq[idx];
dmasound.trans_write = &transQ40Normal;
} else
dmasound.trans_write = &transQ40Expanding;
Q40Silence();
if (dmasound.hard.speed > 20200) {
/* squeeze the sound, we do that */
dmasound.hard.speed = 20000;
dmasound.trans_write = &transQ40Compressing;
} else if (dmasound.hard.speed > 10000) {
dmasound.hard.speed = 20000;
} else {
dmasound.hard.speed = 10000;
}
expand_bal = -dmasound.soft.speed;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 196 | 98.49% | 1 | 50.00% |
dave jones | dave jones | 3 | 1.51% | 1 | 50.00% |
| Total | 199 | 100.00% | 2 | 100.00% |
static int Q40SetFormat(int format)
{
/* Q40 sound supports only 8bit modes */
switch (format) {
case AFMT_QUERY:
return(dmasound.soft.format);
case AFMT_MU_LAW:
case AFMT_A_LAW:
case AFMT_S8:
case AFMT_U8:
break;
default:
format = AFMT_S8;
}
dmasound.soft.format = format;
dmasound.soft.size = 8;
if (dmasound.minDev == SND_DEV_DSP) {
dmasound.dsp.format = format;
dmasound.dsp.size = 8;
}
Q40Init();
return(format);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 96 | 100.00% | 1 | 100.00% |
| Total | 96 | 100.00% | 1 | 100.00% |
static int Q40SetVolume(int volume)
{
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 12 | 100.00% | 1 | 100.00% |
| Total | 12 | 100.00% | 1 | 100.00% |
/*** Machine definitions *****************************************************/
static SETTINGS def_hard = {
.format = AFMT_U8,
.stereo = 0,
.size = 8,
.speed = 10000
} ;
static SETTINGS def_soft = {
.format = AFMT_U8,
.stereo = 0,
.size = 8,
.speed = 8000
} ;
static MACHINE machQ40 = {
.name = "Q40",
.name2 = "Q40",
.owner = THIS_MODULE,
.dma_alloc = Q40Alloc,
.dma_free = Q40Free,
.irqinit = Q40IrqInit,
#ifdef MODULE
.irqcleanup = Q40IrqCleanUp,
#endif /* MODULE */
.init = Q40Init,
.silence = Q40Silence,
.setFormat = Q40SetFormat,
.setVolume = Q40SetVolume,
.play = Q40Play,
.min_dsp_speed = 10000,
.version = ((DMASOUND_Q40_REVISION<<8) | DMASOUND_Q40_EDITION),
.hardware_afmts = AFMT_U8, /* h'ware-supported formats *only* here */
.capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
};
/*** Config & Setup **********************************************************/
static int __init dmasound_q40_init(void)
{
if (MACH_IS_Q40) {
dmasound.mach = machQ40;
dmasound.mach.default_hard = def_hard ;
dmasound.mach.default_soft = def_soft ;
return dmasound_init();
} else
return -ENODEV;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 29 | 63.04% | 1 | 33.33% |
dave jones | dave jones | 16 | 34.78% | 1 | 33.33% |
adrian bunk | adrian bunk | 1 | 2.17% | 1 | 33.33% |
| Total | 46 | 100.00% | 3 | 100.00% |
static void __exit dmasound_q40_cleanup(void)
{
dmasound_deinit();
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 12 | 100.00% | 1 | 100.00% |
| Total | 12 | 100.00% | 1 | 100.00% |
module_init(dmasound_q40_init);
module_exit(dmasound_q40_cleanup);
MODULE_DESCRIPTION("Q40/Q60 sound driver");
MODULE_LICENSE("GPL");
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 2173 | 76.35% | 1 | 6.25% |
dave jones | dave jones | 505 | 17.74% | 1 | 6.25% |
alan cox | alan cox | 48 | 1.69% | 1 | 6.25% |
peter waechtler | peter waechtler | 43 | 1.51% | 1 | 6.25% |
geert uytterhoeven | geert uytterhoeven | 32 | 1.12% | 4 | 25.00% |
linus torvalds | linus torvalds | 23 | 0.81% | 4 | 25.00% |
al viro | al viro | 11 | 0.39% | 2 | 12.50% |
andrew morton | andrew morton | 10 | 0.35% | 1 | 6.25% |
adrian bunk | adrian bunk | 1 | 0.04% | 1 | 6.25% |
| Total | 2846 | 100.00% | 16 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.