ckfwq/linux-3.0.4/drivers/char/gsc3280_adctest.c

231 lines
5.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <gsc3280/timer.h>
#define ADC_DEBUG 1
#ifdef ADC_DEBUG
#define dbg(msg...) printk(KERN_INFO msg)
#else
#define dbg(msg...) do{}while(0)
#endif
static void adcinit ( void )
{
unsigned int rsl = 0;
int c = 0;
*(volatile unsigned int *)0xbc04a00c |= 0x10;
*(volatile unsigned int *)0xbc04a0ac = 0x1; //enable adc & touchScreen
/*SPI0 CONFIG */
*((volatile unsigned int *)0xbc04a008) |= (1<<3);//spi0 clk enable
*((volatile unsigned int *)0xbc04a0b0) |= (1<<29);//spi0 iomux
*((volatile unsigned int *)0xbc04a0ac) = 0x1; //enable tsc
*((volatile unsigned int *)0xbc04a034) = 0x13;//PCLK 20 div
*((volatile unsigned int *)0xbc101004) = 0x1;//SPI_CLK 40 div
//*((volatile unsigned int *)0xbc101000) = 0x6f07;//MODE3,DATA WIDTH 16BIT
*((volatile unsigned int *)0xbc101000) = 0x6fc7;
msleep(300);
*(volatile unsigned int *) 0xbc101050 = 0x0; //cs0 enable
while(1)
{
*(volatile unsigned int *)0xbc101024 = 0x0;
while( *(volatile unsigned int *)0xbc101018 & 0x10 );
rsl = *(volatile unsigned int *)0xbc101024;
if(rsl == 0x8000)
break;
if(c++ > 1000)
{
break;
}
}
}
static int auto_adc(unsigned int cmd)
{
unsigned int res = 0;
//unsigned int value = cmd;
*((volatile unsigned int *)0xbc101050) = 0x0; //spi0片选使能
*((volatile unsigned int *)0xbc101080) = 0x1; //自动采样使能
*((volatile unsigned int *)0xbc101060) = 0xf; //ADC通道选择
//*((volatile unsigned int *)0xbc101070) = 0x10; //ADC采样数目
*((volatile unsigned int *)0xbc101090) = 0x1; //自动采样开始
printk(KERN_INFO "SPI_CSN is 0x%x \n" , *(volatile unsigned int *)0xbc101050 );
printk(KERN_INFO "SPI_ADC_TRIGGER is 0x%x \n" , *(volatile unsigned int *)0xbc101090 );
dbg("start adc...\n");
while(1)
{
//while(!((*((volatile unsigned int *)0xbc101018))&0x4)); //一直等待状态寄存器非空
//res = *((volatile unsigned int *)0xbc101024); //read data from fifo
//while((readl(0xbc101018)&0x4)==0);
res = readl(0xbc101024); //read data from fifo
dbg("auto adc res = 0x%x\n",res&0xfff);
//dbg("auto adc res = 0x%x\n",res);
msleep(100);
}
return 0;
}
static int GetVolt(unsigned int cmd)
{
unsigned int res = 0;
*((volatile unsigned int *)0xbc101050) = 0x0;//cs0 enable这个片选仅作为ADC内部使用
*((volatile unsigned int *)0xbc101024) = cmd; //spi数据寄存器将命令写入发送fifo测量通道ADC通道1
while ( 1 )
{
while(!((*((volatile unsigned int *)0xbc101018))&0x4)); //一直等待状态寄存器非空
res = *((volatile unsigned int *)0xbc101024); //read data from fifo
//dbg("res = %d\n",res);
if ( res == 0xF000 || res == (0x8000|(cmd>>12)) )
{
*((volatile unsigned int *)0xbc101024) = 0xF000; //NOP命令
}
else if ( res < 0x1000 )
{
*((volatile unsigned int *)0xbc101050) = 0x1; //片选关闭
dbg("GetVolt res = %d\n",res);
break;
}
else
//dbg("xxxxx\n");
*((volatile unsigned int *)0xbc101024) = 0x9000; //采样ADC0通道??
}
printk(KERN_INFO "GetVolt return\n");
return res;
}
static ssize_t adctest_read ( struct file * pfile , char __user * pbuf , size_t size , loff_t * ppos )
{
size_t size_m=2*1024*1024;
char *buf;
char buf_t[10];
int i;
#if 0
uint8_t read_buffer[2];
unsigned int volt= GetVolt(0xa000);
read_buffer[0]=volt&0xff;
read_buffer[1]=(volt>>8)&0xff;
copy_to_user(pbuf, read_buffer, 2);
//auto_adc(0);
#endif
buf=kmalloc(size_m, GFP_KERNEL);
if (!buf)
return -ENOMEM;
printk(KERN_INFO "kmalloc ok! \n");
memset(buf,0xaa,size_m);
// memcpy(buf_t ,buf, 10);
// for(i=0;i<10;i++)
// printk(KERN_INFO "buf_t[%d]=%x \n",i, buf_t[i]);
copy_to_user(pbuf, buf, size);
kfree(buf);
return 0;
}
static int adctest_open ( struct inode * node , struct file * file )
{
return 0 ;
}
static int adctest_release ( struct inode * node , struct file * file )
{
return 0 ;
}
static struct file_operations m_fileadctest = {
.owner = THIS_MODULE ,
.llseek = no_llseek ,
.read = adctest_read ,
.unlocked_ioctl = NULL,
.open = adctest_open ,
.release = adctest_release ,
} ;
static struct miscdevice m_deviceAdc = {
.minor = MISC_DYNAMIC_MINOR ,
.name = "adctest",
.fops = & m_fileadctest ,
} ;
static int __init adctest_init ( void )
{
int result;
result = misc_register ( &m_deviceAdc ) ;
if ( result == 0 )
{
dbg("adc init...\n");
adcinit ( );
dbg("adc init ok ...\n");
}
else
{
printk ( KERN_WARNING "register device error !!!!\n") ;
}
return result ;
}
static void __exit adctest_exit ( void )
{
misc_deregister ( & m_deviceAdc ) ;
return ;
}
module_init ( adctest_init ) ;
module_exit ( adctest_exit ) ;
MODULE_AUTHOR ( "lufei" ) ;
MODULE_LICENSE ( "Dual BSD/GPL" ) ;