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 );
查看全文
相关阅读:
DataWhale《零基础入门数据挖掘》第二次打卡
成功解决socket.timeout: The read operation timed out问题
Pandas函数set_option()学习笔记
[打卡]动手学深度学习第四次打卡
[打卡]动手学深度学习第三次打卡
[深度学习]动手学深度学习笔记-15
[深度学习]动手学深度学习笔记-14
[深度学习]动手学深度学习笔记-13
[深度学习]动手学深度学习笔记-12
jsp标准标签库——jstl
原文地址:https://www.cnblogs.com/zym0805/p/4847574.html
最新文章
PHP 二位数组按照下标排序
一个二维数组根据某个字段相加然后去重的操作
根据二位数组的某个字段删除多余的一维数组
关于快递鸟的顺丰电子面单打印
关于菜鸟的圆通电子面单打印
tp5怎么实现搜索分页能保留搜索条件
关于钉钉发送普通消息的接口操作
TP5 数组分页
jquery 记住账号 记住密码
laravel 分页带参数
热门文章
go
mysql 使用concat模糊查询
laravel 表单验证
laravel 参数设置
laravle 事务
卡包模板
阿里云调试未知错误
微信新增图片信息
TP3.2的URL重写省略index.php问题
角度与弧度间的转换(Python实现)
Copyright © 2011-2022 走看看