📄 tlc3544a.c~
字号:
/* * FileName tlc3544a.h * Author wangzhenhui * Date 09/21/06 * Board SESI_AT91RM9200EDUKIT * A/D driver */#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/fs.h> /* everything... */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/proc_fs.h>#include <linux/fcntl.h> /* O_ACCMODE */#include <linux/seq_file.h>#include <linux/cdev.h>#include <linux/delay.h>#include <asm/system.h> /* cli(), *_flags */#include <asm/uaccess.h> /* copy_*_user */#include <asm/arch/board.h>#include <asm/arch/gpio.h>#include <asm/hardware.h>#include <linux/interrupt.h>#include <asm/irq.h>#include "tlc3544.h"static int tlc3544_open(struct inode *, struct file *);static int tlc3544_close(struct inode *, struct file *);static int tlc3544_read(struct file *, char *, size_t, loff_t *);static int tlc3544_write(struct file *, const char *, size_t, loff_t *);static void tlc3544_hardware_init(void);static void Command(int);static int ReadData(int);static void InitAD(void);static int Cal(int); int tlc3544_major = 0;int tlc3544_minor = 0;struct tlc3544_dev *tlc3544_device;int first=0;int channel=0;static struct file_operations tlc3544_fops = { open: tlc3544_open, read: tlc3544_read, write: tlc3544_write, release: tlc3544_close,};static void Command(int command)
{
int i,SDIdata;
long int mask;
at91_set_gpio_value(CS,1);
at91_set_gpio_value(CS,0);
//ÉèÖÃÃüÁSDI bit[15:12]=1010b
for(i=0,mask=0x8000;i<16;i++,mask=mask>>1)
{
SDIdata=command&mask;
if(SDIdata==mask)
at91_set_gpio_value(SDI,1);
else
at91_set_gpio_value(SDI,0);
at91_set_gpio_value(SCLK,1);
at91_set_gpio_value(SCLK,0);
udelay(10);
}
}static int ReadData(int command)
{
int i,j,result,SDIdata;
long int mask;
at91_set_gpio_value(CS,1);
at91_set_gpio_value(CS,0);
//¶ÁÈ¡žß12λµÄ×ÖœÚÊýŸÝ
for(i=0,mask=0x8000;i<16;i++,mask=mask>>1)
{
SDIdata=command&mask;
if(SDIdata==mask)
at91_set_gpio_value(SDI,1);
else
at91_set_gpio_value(SDI,0);
at91_set_gpio_value(SCLK,1);
at91_set_gpio_value(SCLK,0);
j=at91_get_gpio_value(SDO);
result+=j;
result=result<<1;
udelay(10);
}
result=result>>1;
return (result&0xFFFC);
}static void InitAD(void)
{
Command(0xa204); // user internal reference 0xa204 ueser external referencd
ReadData(0x1000);
}static int Cal(int result)
{
int v;
v=0;
v=(result>>2)*4000/16383;
return v;
}
static void tlc3544_hardware_init (void){ printk("tlc3544_hardware_init\n"); at91_set_gpio_output(CS,1); at91_set_gpio_output(SDI,1); at91_set_gpio_output(SCLK,1); at91_set_gpio_input(SDO,1); at91_set_gpio_input(EOC,1); at91_set_gpio_value(CS,0); at91_set_gpio_value(SDI,0); at91_set_gpio_value(SCLK,0); InitAD(); }static int tlc3544_open (struct inode *inode, struct file *file){ printk("tlc3544_open\n"); tlc3544_device->use_count++; if(tlc3544_device->use_count==1)file->private_data = tlc3544_device; return 0;}static int tlc3544_close (struct inode *inode, struct file *file){ printk("tlc3544_close\n"); tlc3544_device->use_count--; return 0;}static int tlc3544_read (struct file *file, char *buf, size_t count, loff_t *ppos){ int result=0; int tmp=0; char data; first++; if(channel==0) tmp=ReadData(0x0000); if(channel==3) tmp=ReadData(0x3000); if(first!=1) { result=Cal(tmp);//printk("result: %d\n",result); data=result;printk("data: %d\n",data); put_user(data,buf); //put_user(result,buf); } return count;}static int tlc3544_write (struct file *file, const char *buf, size_t count, loff_t *ppos){ char data; get_user(data, buf); if(data==0) channel=0; if(data==3) channel=3; // printk("channel: %d\n", channel); return count; }void tlc3544_cleanup_module(void){ dev_t devno = MKDEV(tlc3544_major, tlc3544_minor); printk("tlc3544 module cleanup.\n"); cdev_del(&tlc3544_device->cdev); kfree(tlc3544_device); unregister_chrdev_region(devno, 1); }int tlc3544_init_module(void){ int result,dev_no; dev_t dev = 0; tlc3544_hardware_init (); /* ask for a dynamic major */ result = alloc_chrdev_region(&dev, tlc3544_minor, 0, "tlc3544"); tlc3544_major = MAJOR(dev); if (result < 0) { printk(KERN_WARNING "tlc3544: can't get major %d\n", tlc3544_major); return result; } /* mem alloc for device */ tlc3544_device = kmalloc(sizeof(struct tlc3544_dev), GFP_KERNEL); if (!tlc3544_device) { result = -ENOMEM; printk(KERN_WARNING "ads 7843 memory alloc failed.\n"); goto fail; /* Make this more graceful */ } memset(tlc3544_device, 0, sizeof(struct tlc3544_dev)); /* init mutex */ init_MUTEX(&(tlc3544_device->sem)); /* reg device */ dev_no = MKDEV(tlc3544_major, tlc3544_minor); cdev_init(&tlc3544_device->cdev, &tlc3544_fops); tlc3544_device->cdev.owner = THIS_MODULE; tlc3544_device->cdev.ops = &tlc3544_fops; result = cdev_add (&tlc3544_device->cdev, dev_no, 1); /* Fail gracefully if need be */ if (result){ printk(KERN_NOTICE "Error %d adding tlc3544.\n", result); goto fail; } printk("tlc3544 module init major:%d.\n",tlc3544_major); return 0;fail: tlc3544_cleanup_module(); return result;}module_init(tlc3544_init_module);module_exit(tlc3544_cleanup_module);MODULE_AUTHOR("Zhenhui wang, wangzhenhui2002@hotmail.com");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -