#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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" ) ;