zoukankan
html css js c++ java
ad7888 linux driver
/*
ADCCONVERT.c :
Generate ADC signals from SPI ports, as the A/D control signals.
Author: Aaron Fu
2008-10-14
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h> /* kmalloc */
#include <linux/fs.h> /* struect file inode */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h> /* proc_fs */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h> /* seq_file */
#include <linux/cdev.h> /* register char device */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include <asm/delay.h> /* udelay */
#include <asm/io.h> /* ioremap...*/
#include "adconvert.h" /* local definitions */
int adc_major = ADC_MAJOR;
int adc_minor = 0;
int adc_nr_devs = ADC_NR_DEVS;
static
int adcopen;
struct cdev *adc_cdev;
module_param( adc_major,
int, S_IRUGO );
module_param( adc_minor,
int, S_IRUGO );
module_param( adc_nr_devs,
int, S_IRUGO );
MODULE_LICENSE(
"Aaron Fu" );
MODULE_DESCRIPTION(
"Iconic Shanghai Co.,LTD." );
MODULE_AUTHOR(
"GPL" );
void adc_address_map(
void){
r_SPSTA0 = ioremap( rSPSTA0, 0x00000004 );
r_SPPRE0 = ioremap( rSPPRE0, 0x00000004 );
// rSPPRE0
r_SPCON0 = ioremap( rSPCON0, 0x00000004 );
// rSPCON0
r_SPTDAT0 = ioremap( rSPTDAT0, 0x00000004 );
// rSPTDAT0
r_SPRDAT0 = ioremap( rSPRDAT0, 0x00000004 );
r_GPECON = ioremap( rGPECON, 0x00000004 );
//rGPECON
r_GPEUP = ioremap( rGPEUP, 0x00000004 );
// rGPEUP
r_GPHCON = ioremap( rGPHCON, 0x00000004 );
// rGPHCON
r_GPHUP = ioremap( rGPHUP, 0x00000004 );
// rGPHUP
r_GPHDAT = ioremap( rGPHDAT, 0x00000004 );
//rGPHDAT
}
void adc_cancel_add_map(
void ){
iounmap( r_SPSTA0 );
iounmap( r_SPPRE0 );
iounmap( r_SPCON0 );
iounmap( r_SPTDAT0 );
iounmap( r_SPRDAT0 );
iounmap( r_GPECON );
iounmap( r_GPEUP );
iounmap( r_GPHCON );
iounmap( r_GPHUP );
iounmap( r_GPHDAT );
}
static
void adc_spi_init(
void ){
int i;
/*
rSPPRE0 = 0x32;
rSPCON0 = 0x1e;
for( i = 0; i < 10; i++ )
rSPTDAT0 = 0xff;
rGPECON |= 0x0a800000;
rGPECON &= ( ~0x05400000 );
rGPEUP |= 0x3800;
//GPH5----->CS
rGPHCON |= 0x0400;
rGPHCON &= ( ~0x0800 );
rGPHUP &= ( ~0x20 );
rGPHDAT |= 0x20;*/
iowrite32( ioread32( r_SPSTA0 ) | 0x01, r_SPSTA0 );
iowrite32( 0x4, r_SPPRE0 );
iowrite32( 0x1e, r_SPCON0 );
for( i = 0; i < 10; i++ ){
iowrite32( 0xff, r_SPTDAT0 );
}
//for( i = 0; i < 10; i++ ){
iowrite32( 0x00, r_SPRDAT0 );
//}
iowrite32( ioread32( r_GPECON ) | 0x0a800000, r_GPECON );
iowrite32( ioread32( r_GPECON ) & ( ~0x05400000 ), r_GPECON );
iowrite32( ioread32( r_GPEUP ) | 0x3800, r_GPEUP );
iowrite32( ioread32( r_GPHCON ) | 0x0400, r_GPHCON );
iowrite32( ioread32( r_GPHCON ) & ( ~0x0800 ), r_GPHCON );
iowrite32( ioread32( r_GPHUP ) & ( ~0x20 ), r_GPHUP );
iowrite32( ioread32( r_GPHDAT ) | ( 0x20 ), r_GPHDAT );
}
static
struct file_operations adc_fops = {
/* driver info */
.owner = THIS_MODULE,
.open = adc_open,
.read = adc_read,
.write = adc_write,
.release = adc_release,
};
static ssize_t adc_write(
struct file *file,
const
char __user *buf,
size_t count, loff_t *offset ){
int ret = 0;
int i = 0;
printk(
"write count value = %d ", count );
dbuf = kmalloc( count *
sizeof( unsigned
char ), GFP_KERNEL);
if ( dbuf == NULL ){
printk( KERN_WARNING
"write: dbuf alloc memory fail " );
return -1;
}
memset( dbuf, 0, count *
sizeof( unsigned
char ) );
copy_from_user( dbuf, buf, count );
printk(
"************** write bufx = %x ******************* ", buf );
printk(
"************* write bufs = %s ******************* ", buf );
for( i = 0; i < count; i++ ){
ADCTxdata[i] = dbuf[i];
printk(
"write adctx value [%d] = %c ", i, ADCTxdata[i] );
}
kfree( dbuf );
return ret;
}
static ssize_t adc_read(
struct file *file,
char __user *buf,
size_t count, loff_t *offset ){
int i = 0;
int ret = 0;
iowrite32( ioread32( r_SPCON0 ) | 0x1, r_SPCON0 );
adc_convert();
adc_convert();
printk(
" " );
printk(
"read count value = %d ", count );
dbuf = kmalloc( count *
sizeof( unsigned
char ), GFP_KERNEL );
if ( dbuf == NULL ){
printk( KERN_WARNING
"read: dbuf alloc memory fail " );
return -1;
}
memset( dbuf, 0, count *
sizeof( unsigned
char ) );
for( i = 0; i < count; i++ ){
dbuf[i] = ADCRxdata[i];
printk(
"read adctx value [%d] = %c ", i, ADCTxdata[i] );
}
printk(
" " );
copy_to_user( buf, dbuf, count);
printk(
"************** read bufx = %x ************************ ", buf );
printk(
"************** read bufs = %s ************************ ", buf );
kfree( dbuf );
return ret;
}
void adc_convert(
void ){
/*rGPHDAT &= ( ~0x20 );
adc_tx_data( ADCTxdata[0] );
// ADCRXdata[0] = rSPRDATO;
ADCRxdata[0] = r_SPRDAT0;
adc_tx_data( 0xff );
// ADCRXdata[1] = rSPRDATO;
ADCRxdata[1] = r_SPRDAT0;
rGPHDAT |= 0x20;*/
iowrite32( ioread32( r_GPHDAT ) & ( 0x20 ), r_GPHDAT );
adc_tx_data( ADCTxdata[0] );
ADCRxdata[0] = r_SPRDAT0;
adc_tx_data( 0xff );
ADCRxdata[1] = r_SPRDAT0;
iowrite32( ioread32( r_GPHDAT ) | ( 0x20 ), r_GPHDAT );
}
static
void adc_tx_data( unsigned
char data ){
iowrite32( ioread32( r_SPSTA0 ) | 0x01, r_SPSTA0 );
spi_poll_done();
//rSPTDAT0 = data;
iowrite32( data, r_SPTDAT0 );
spi_poll_done();
}
void spi_poll_done(
void ){
//while ( !( rSPSTA0 & 0x01 ) )
while ( !( ioread32( r_SPSTA0 ) & 0x01 ) )
;
}
int adc_release(
struct inode *inode,
struct file *filp ){
adcopen--;
module_put( THIS_MODULE );
return 0 ;
}
int adc_init_module(
void ){
int result;
dev_t dev = 0;
if ( adc_major ){
dev = MKDEV( adc_major, adc_minor );
result = register_chrdev_region( dev, adc_nr_devs,
"adc" );
}
else{
result = alloc_chrdev_region( &dev, adc_minor, adc_nr_devs,
"adc" );
adc_major = MAJOR( dev );
}
adc_cdev = cdev_alloc();
if ( adc_cdev == NULL ){
return -1;
}
if ( result < 0 ){
printk( KERN_WARNING
"adc: can't get major %d ", adc_major );
return result;
}
printk( KERN_INFO
"adc: this major is %d ", adc_major );
adcopen = 0;
adc_cdev->ops = &adc_fops;
cdev_init( adc_cdev, &adc_fops );
cdev_add( adc_cdev, dev, 1 );
adc_address_map();
adc_spi_init();
printk( KERN_INFO
"*** adc_init() finished *** " );
return 0;
}
static
int adc_open(
struct inode *inode,
struct file *filp ){
if ( adcopen == 0 )
adcopen++;
else{
printk( KERN_ALERT
"Another process open the char device " );
return -1;
}
try_module_get( THIS_MODULE );
return 0;
}
void adc_cleanup_module(
void ){
dev_t devno;
adc_cancel_add_map();
devno = MKDEV( adc_major, adc_minor );
unregister_chrdev_region( devno, adc_nr_devs );
cdev_del( adc_cdev );
}
module_init( adc_init_module );
module_exit( adc_cleanup_module );
查看全文
相关阅读:
hadoop用到的shell脚本
hadoop搭建完全分布式集群
hadoop搭建伪分布式集群
ARM Compute Library编译安装
OpenBlas交叉编译安装
正则表达式去除所有标签html标签
xstream实现xml字符串与对象直接的转换
spring-boot中使用mybatis-plus代码生成器让你轻松的完成单表的CURD
开源、免费软件和网站分享
2020春软件工程助教工作期末总结
原文地址:https://www.cnblogs.com/zym0805/p/4847574.html
最新文章
NOI前做题记录
工作感受月记202008月
springboot整合Druid加密 及连接错误处理
对称二叉树
耗哥20200807直播笔记
二叉树的深度
二叉树的所有路径
路径总和
N 叉树的最大深度
二叉树的最近公共祖先
热门文章
二叉树的层次遍历2
层次遍历
单值二叉树
Reduce Join
Map Join与计数器
Combiner合并
分区(partition)和全排序(WritableComparable)
GroupingComparator分组(辅助分组)和二次排序
HadoopHA(高可用集群)
Hadoop(MapReducer)面试题
Copyright © 2011-2022 走看看