#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/io.h>
const int major = 250;
const int minjor = 0;
const char *drvname = "adc_convertor";
char readbuf[5] = "asdfg";
struct cdev adcDev;
unsigned int *ADCCON;
unsigned int *ADCMUX;
unsigned int *ADCDAT0;
int chenhao_open (struct inode* inode, struct file* filp )
{
printk(KERN_ALERT"hello, chenhao dev is open");
return 0;
}
int chenhao_release(struct inode* inode, struct file* filp )
{
printk(KERN_ALERT"chenhao dev is close");
return 0;
}
const char adsheet[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
int chenhao_read( struct file* filp, char __user* buffer, int len, loff_t* offset)
{
if ( len > sizeof(readbuf) )
{
len = sizeof(readbuf);
}
// while(! ((*ADCCON) & 0x8000));
unsigned int adcdata;
adcdata = 1111111;
// adcdata = ((*ADCDAT0) & 0x3ff);
adcdata = adcdata * 3.3;
int bit4 = adcdata/1000;
readbuf[3] = adsheet[bit4];
int bit3 = (adcdata%1000)/100;
readbuf[2] = adsheet[bit3];
int bit2 = ((adcdata%1000)%100)/10;
readbuf[1] = adsheet[bit2];
int bit1 = (((adcdata%1000)%100)%10)%10;
readbuf[0] = adsheet[bit1];
copy_to_user( buffer, readbuf , len );
return len;
}
int chenhao_write ( struct file* filp, const char __user* buffer, int len, loff_t* offset)
{
if ( len>sizeof(readbuf))
{
len = sizeof(readbuf) -1 ;
}
copy_from_user( readbuf, buffer , len);
readbuf[len] = '\0';
return len;
}
#define SWITCH_MAGIC 'a'
#define NUM_ONE _IO( SWITCH_MAGIC,1 )
#define NUM_TWO _IO( SWITCH_MAGIC,2 )
int chenhao_ioctl( struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg )
{
switch( cmd )
{
case NUM_ONE:
*ADCMUX = 0;
// printk(KERN_ALERT" This ioctl arg =0x%x\r\n", ADCCON);
break;
case NUM_TWO:
*ADCMUX= 1;
// printk(KERN_ALERT"This ioctl arg = 0x%x\r\n" ,ADCCON);
break;
default:
break;
}
}
struct file_operations my_hello_ops =
{
.owner = THIS_MODULE,
.open = chenhao_open,
.release = chenhao_release,
.read = chenhao_read,
.write = chenhao_write,
.ioctl = chenhao_ioctl
};
int chenhao_init(void)
{
int ret;
dev_t devnum = MKDEV( major, minjor );
ret = register_chrdev_region( devnum, 1 , "adc_dev" );
if ( ret<0 )
{
return ret;
}
cdev_init( &adcDev, &my_hello_ops );
ret = cdev_add ( &adcDev, devnum, 1 );
if ( ret )
{
goto err;
}
// int preScaler = 65;
ADCCON = ioremap( 0xf3000000, 4 );
*ADCCON = (1<<14)| (65<<6)| (0<<3) | (0<<2) | (1<<1);
ADCMUX = ioremap( 0xf300001c, 4 );
ADCDAT0 = ioremap( 0xf300000c, 4);
printk(KERN_ALERT"module install %s \r\n",drvname);
return 0;
err:
unregister_chrdev_region ( MKDEV(major,minjor), 1 );
return -ret;
}
void chenhao_cleanup(void)
{
iounmap( ADCCON );
iounmap( ADCMUX );
iounmap( ADCDAT0);
cdev_del (&adcDev );
unregister_chrdev_region ( MKDEV(major,minjor), 1 );
printk(KERN_ALERT"module install %s \r\n",drvname);
}
module_init( chenhao_init );
module_exit( chenhao_cleanup );
MODULE_AUTHOR( "chen hao ");
MODULE_DESCRIPTION( " This is my hello simple module ");
MODULE_LICENSE ( "GPL" );