⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adconvert.c

📁 linux下ad7888使用spi口驱动程序代码
💻 C
字号:
/*        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\n", count );    dbuf = kmalloc( count * sizeof( unsigned char ), GFP_KERNEL);    if ( dbuf == NULL ){    	printk( KERN_WARNING "write: dbuf alloc memory fail\n" );    	return -1;    }    memset( dbuf, 0, count *sizeof( unsigned char ) );    copy_from_user( dbuf, buf, count );    printk( "**************  write bufx = %x  *******************\n", buf );        printk( "*************   write bufs = %s  *******************\n", buf );    for( i = 0; i < count; i++ ){    	ADCTxdata[i] = dbuf[i];        printk( "write adctx value [%d] = %c\n", 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( "\n\n" );    printk( "read count value = %d\n", count );        dbuf = kmalloc( count * sizeof( unsigned char ), GFP_KERNEL );    if ( dbuf == NULL ){    	printk( KERN_WARNING "read: dbuf alloc memory fail\n" );    	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\n", i, ADCTxdata[i] );    }    printk( "\n" );        copy_to_user( buf, dbuf, count);    printk( "**************  read bufx = %x  ************************\n", buf );    printk( "**************  read bufs = %s  ************************\n", 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\n", adc_major );		return result;	}	printk( KERN_INFO "adc: this major is %d\n", 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    *** \n" );	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\n" );		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 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -