|
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/arch/s3c44b0x.h>
#define WAVE_MAJOR 235
#define WAVE_DEVNAME "WavePlayer"
#define WAVE_PAGE_SIZE 1024
#define WAVE_INIT _IO(0xD0, 0)
#define WAVE_RESET _IO(0xD0, 1)
#define WAVE_PLAY _IO(0xD0, 2)
#define WAVE_STOP _IO(0xD0, 3)
//////////////////////////// declaration of key functions /////////////////////
int wave_open(struct inode *inode, struct file *file);
int wave_release(struct inode *inode, struct file *file);
int wave_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param);
int wave_read(struct file *file, const char *buf, size_t count, loff_t *offp);
int wave_write(struct file *file, const char *buf, size_t count, loff_t *offp);
int wave_init(void);
int wave_cleanup(void);
struct file_operations wave_fop = {
owner: THIS_MODULE,
open: wave_open,
release: wave_release,
ioctl: wave_ioctl,
read: wave_read,
write: wave_write
};
char *kbuf;
unsigned char *pWave;
unsigned char *cur_pos;
int wave_size;
/////////////////////////// implemetation of every functions //////////////////
int wave_open(struct inode *inode, struct file *file)
{
printk("Open WavePlayer module.\n");
kbuf = kmalloc(WAVE_PAGE_SIZE, GFP_KERNEL);
pWave = (unsigned char *)kbuf;
wave_size = 0;
MOD_INC_USE_COUNT;
return 0;
}
int wave_release(struct inode *inode, struct file *file)
{
printk("Release WavePlayer module.\n");
kfree(kbuf);
(*(volatile unsigned *)S3C44B0X_BDICNT0) = 0x0;
(*(volatile unsigned *)S3C44B0X_IISCON) = 0x0;
MOD_DEC_USE_COUNT;
return 0;
}
int wave_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
{
if(cmd == WAVE_RESET)
{
cur_pos = kbuf;
}
else if(cmd == WAVE_INIT)
{
printk("config IIS.\n");
(*(volatile unsigned *)S3C44B0X_PCONF) = 0x24900a;
(*(volatile unsigned *)S3C44B0X_IISCON) = 0x22; //master mode, IIS format, 16bits data, master clock: 256fs, serial bit clock: 32 fs
(*(volatile unsigned *)S3C44B0X_IISMOD) = 0x89;
(*(volatile unsigned *)S3C44B0X_IISPSR) = 0x33;
(*(volatile unsigned *)S3C44B0X_IISFIFCON) = 0xa00;
printk("Config DMA.\n");
(*(volatile unsigned *)S3C44B0X_BDISRC0) = (1<<30)+(1<28)+(unsigned long )pWave;
(*(volatile unsigned *)S3C44B0X_BDIDES0) = (1<<30)+(3<<28)+(unsigned long )S3C44B0X_IISFIF;
(*(volatile unsigned *)S3C44B0X_BDICNT0) = (1<<30)+(1<<26)+(3<<22)+(1<<21)+(1<<20)+wave_size;
(*(volatile unsigned *)S3C44B0X_BDCON0) = 0x0;
printk("buffer length: %d\n", wave_size);
}
else if(cmd == WAVE_PLAY)
{
(*(volatile unsigned *)S3C44B0X_IISCON) |= 0x1;
}
else if(cmd == WAVE_STOP)
{
(*(volatile unsigned *)S3C44B0X_BDICNT0) = 0x0;
(*(volatile unsigned *)S3C44B0X_IISCON) = 0x0;
}
return 0;
}
int wave_read(struct file *file, const char *buf, size_t count, loff_t *offp)
{
}
int wave_write(struct file *file, const char *buf, size_t count, loff_t *offp)
{
int old_PLLCON;
copy_from_user(cur_pos, buf, count);
printk("Copied from user. count = %d\n", count);
cur_pos += count;
//old_PLLCON = (*(volatile unsigned *)S3C44B0X_PLLCON);
//(*(volatile unsigned *)S3C44B0X_PLLCON) = (0X69<<12)|(0X17<<4)|0;
//pWave += 0x28;
//wave_size = *(pWave + 0)|*(pWave + 1)<<8|*(pWave + 2)<<16|*(pWave + 3)<<24;
//pWave += 4;
//wave_size = (wave_size>>1)<<1;
//config DMA0
//printk("laying wave......\n");
//(*(volatile unsigned *)S3C44B0X_PLLCON) = old_PLLCON ;
}
int wave_init(void)
{
int ret;
ret = register_chrdev(WAVE_MAJOR, WAVE_DEVNAME, &wave_fop);
if(ret < 0)
printk("Could register wave device with major %n\n", WAVE_MAJOR);
else
printk("Registered wave device succesfully!\n");
return 0;
}
int wave_cleanup(void)
{
unregister_chrdev(WAVE_MAJOR, WAVE_DEVNAME);
return 0;
}
MODULE_AUTHOR("Cricket");
MODULE_LICENSE("GPL");
这样播放WAV文件有问题吗?
数据我是通过write在用户程序写进来的 |
|