zoukankan      html  css  js  c++  java
  • ad7888 linux driver


    1. /* 
    2.         ADCCONVERT.c : 
    3.                 Generate ADC signals from SPI ports, as the A/D control signals. 
    4.  
    5.         Author:  Aaron Fu 
    6.         2008-10-14 
    7. */  
    8.   
    9. #include <linux/module.h>  
    10. #include <linux/moduleparam.h>  
    11. #include <linux/init.h>  
    12.   
    13. #include <linux/kernel.h>   
    14. #include <linux/slab.h>       /* kmalloc */  
    15. #include <linux/fs.h>     /* struect file inode */  
    16. #include <linux/errno.h>  /* error codes */  
    17. #include <linux/types.h>  /* size_t */  
    18. #include <linux/proc_fs.h>    /* proc_fs */  
    19. #include <linux/fcntl.h>  /* O_ACCMODE */  
    20. #include <linux/seq_file.h> /* seq_file */  
    21. #include <linux/cdev.h>       /* register char device */  
    22.   
    23. #include <asm/system.h>       /* cli(), *_flags */  
    24. #include <asm/uaccess.h>  /* copy_*_user */  
    25. #include <asm/delay.h>        /* udelay */  
    26. #include <asm/io.h>           /* ioremap...*/  
    27.   
    28. #include "adconvert.h"      /* local definitions */  
    29.   
    30. int adc_major   = ADC_MAJOR;  
    31. int adc_minor   = 0;  
    32. int adc_nr_devs = ADC_NR_DEVS;  
    33.   
    34. static int      adcopen;  
    35. struct cdev     *adc_cdev;  
    36.   
    37. module_param( adc_major, int, S_IRUGO );  
    38. module_param( adc_minor, int, S_IRUGO );  
    39. module_param( adc_nr_devs, int, S_IRUGO );  
    40.   
    41. MODULE_LICENSE( "Aaron Fu" );  
    42. MODULE_DESCRIPTION( "Iconic Shanghai Co.,LTD." );  
    43. MODULE_AUTHOR( "GPL" );  
    44.   
    45. void adc_address_map(void){  
    46.     r_SPSTA0    =   ioremap( rSPSTA0, 0x00000004 );  
    47.       
    48.     r_SPPRE0    =   ioremap( rSPPRE0, 0x00000004 );         // rSPPRE0  
    49.     r_SPCON0    =   ioremap( rSPCON0, 0x00000004 );         // rSPCON0  
    50.     r_SPTDAT0   =   ioremap( rSPTDAT0, 0x00000004 );        // rSPTDAT0  
    51.     r_SPRDAT0   =   ioremap( rSPRDAT0, 0x00000004 );  
    52.       
    53.     r_GPECON    =   ioremap( rGPECON, 0x00000004 );     //rGPECON  
    54.     r_GPEUP     =   ioremap( rGPEUP, 0x00000004 );          // rGPEUP  
    55.       
    56.     r_GPHCON    =   ioremap( rGPHCON, 0x00000004 );     // rGPHCON  
    57.     r_GPHUP     =   ioremap( rGPHUP, 0x00000004 );          // rGPHUP  
    58.     r_GPHDAT    =   ioremap( rGPHDAT, 0x00000004 );     //rGPHDAT  
    59. }  
    60.   
    61. void adc_cancel_add_map( void ){  
    62.     iounmap( r_SPSTA0 );  
    63.     iounmap( r_SPPRE0 );  
    64.     iounmap( r_SPCON0 );  
    65.     iounmap( r_SPTDAT0 );  
    66.     iounmap( r_SPRDAT0 );  
    67.     iounmap( r_GPECON );  
    68.     iounmap( r_GPEUP );  
    69.     iounmap( r_GPHCON );  
    70.     iounmap( r_GPHUP );  
    71.     iounmap( r_GPHDAT );  
    72. }  
    73.   
    74. static void adc_spi_init( void ){  
    75.     int i;  
    76.       
    77.     /* 
    78.     rSPPRE0 = 0x32; 
    79.     rSPCON0 = 0x1e; 
    80.     for( i = 0; i < 10; i++ ) 
    81.         rSPTDAT0 = 0xff;     
    82.     
    83.     rGPECON |= 0x0a800000; 
    84.     rGPECON &= ( ~0x05400000 ); 
    85.     rGPEUP |= 0x3800; 
    86.     //GPH5----->CS 
    87.     rGPHCON |= 0x0400; 
    88.     rGPHCON &= ( ~0x0800 ); 
    89.     rGPHUP &= ( ~0x20 ); 
    90.     rGPHDAT |= 0x20;*/  
    91.       
    92.     iowrite32( ioread32( r_SPSTA0 ) | 0x01, r_SPSTA0 );  
    93.       
    94.     iowrite32( 0x4, r_SPPRE0 );  
    95.     iowrite32( 0x1e, r_SPCON0 );  
    96.      
    97.     for( i = 0; i < 10; i++ ){  
    98.         iowrite32( 0xff, r_SPTDAT0 );  
    99.     }  
    100.   
    101.     //for( i = 0; i < 10; i++ ){  
    102.         iowrite32( 0x00, r_SPRDAT0 );  
    103.     //}  
    104.      
    105.     iowrite32( ioread32( r_GPECON ) | 0x0a800000, r_GPECON );  
    106.     iowrite32( ioread32( r_GPECON ) & ( ~0x05400000 ), r_GPECON );  
    107.     iowrite32( ioread32( r_GPEUP ) | 0x3800, r_GPEUP );  
    108.       
    109.     iowrite32( ioread32( r_GPHCON ) | 0x0400, r_GPHCON );  
    110.     iowrite32( ioread32( r_GPHCON ) & ( ~0x0800 ), r_GPHCON );  
    111.     iowrite32( ioread32( r_GPHUP ) & ( ~0x20 ), r_GPHUP );  
    112.     iowrite32( ioread32( r_GPHDAT ) | ( 0x20 ), r_GPHDAT );  
    113. }  
    114.       
    115. static struct file_operations adc_fops = {        /* driver info  */  
    116.     .owner      =       THIS_MODULE,  
    117.     .open       =       adc_open,  
    118.     .read       =       adc_read,  
    119.     .write      =       adc_write,  
    120.     .release    =       adc_release,  
    121. };  
    122.   
    123.   
    124. static ssize_t adc_write( struct file *file, const char __user *buf, size_t count, loff_t *offset ){  
    125.     int ret = 0;  
    126.     int i = 0;  
    127.       
    128.     printk( "write count value = %d ", count );  
    129.     dbuf = kmalloc( count * sizeof( unsigned char ), GFP_KERNEL);  
    130.     if ( dbuf == NULL ){  
    131.         printk( KERN_WARNING "write: dbuf alloc memory fail " );  
    132.         return -1;  
    133.     }  
    134.     memset( dbuf, 0, count *sizeof( unsigned char ) );  
    135.   
    136.     copy_from_user( dbuf, buf, count );  
    137.     printk( "**************  write bufx = %x  ******************* ", buf );      
    138.     printk( "*************   write bufs = %s  ******************* ", buf );  
    139.     for( i = 0; i < count; i++ ){  
    140.         ADCTxdata[i] = dbuf[i];  
    141.         printk( "write adctx value [%d] = %c ", i, ADCTxdata[i] );  
    142.     }  
    143.       
    144.     kfree( dbuf );  
    145.   
    146.     return ret;  
    147. }  
    148.     
    149. static ssize_t adc_read( struct file *file, char __user *buf, size_t count, loff_t *offset ){  
    150.     int i = 0;  
    151.     int ret = 0;  
    152.       
    153.     iowrite32( ioread32( r_SPCON0 ) | 0x1, r_SPCON0 );  
    154.     adc_convert();  
    155.     adc_convert();  
    156.     printk( " " );  
    157.     printk( "read count value = %d ", count );  
    158.       
    159.     dbuf = kmalloc( count * sizeof( unsigned char ), GFP_KERNEL );  
    160.     if ( dbuf == NULL ){  
    161.         printk( KERN_WARNING "read: dbuf alloc memory fail " );  
    162.         return -1;  
    163.     }  
    164.     memset( dbuf, 0, count * sizeof( unsigned char ) );  
    165.       
    166.     for( i = 0; i < count; i++ ){  
    167.         dbuf[i] = ADCRxdata[i];  
    168.         printk( "read adctx value [%d] = %c ", i, ADCTxdata[i] );  
    169.     }  
    170.     printk( " " );  
    171.       
    172.     copy_to_user( buf, dbuf, count);  
    173.     printk( "**************  read bufx = %x  ************************ ", buf );  
    174.     printk( "**************  read bufs = %s  ************************ ", buf );  
    175.     kfree( dbuf );  
    176.   
    177.     return ret;  
    178. }  
    179.   
    180. void adc_convert( void ){  
    181.     /*rGPHDAT &= ( ~0x20 ); 
    182.     adc_tx_data( ADCTxdata[0] ); 
    183.     // ADCRXdata[0] = rSPRDATO; 
    184.     ADCRxdata[0] = r_SPRDAT0; 
    185.     adc_tx_data( 0xff ); 
    186.     // ADCRXdata[1] = rSPRDATO; 
    187.     ADCRxdata[1] = r_SPRDAT0; 
    188.     rGPHDAT |= 0x20;*/  
    189.       
    190.     iowrite32( ioread32( r_GPHDAT ) & ( 0x20 ), r_GPHDAT );  
    191.       
    192.     adc_tx_data( ADCTxdata[0] );  
    193.     ADCRxdata[0] = r_SPRDAT0;  
    194.     adc_tx_data( 0xff );  
    195.     ADCRxdata[1] = r_SPRDAT0;  
    196.     iowrite32( ioread32( r_GPHDAT ) | ( 0x20 ), r_GPHDAT );  
    197. }  
    198.   
    199. static void adc_tx_data( unsigned char data ){  
    200.     iowrite32( ioread32( r_SPSTA0 ) | 0x01, r_SPSTA0 );  
    201.     spi_poll_done();  
    202.     //rSPTDAT0 = data;  
    203.     iowrite32( data, r_SPTDAT0 );  
    204.     spi_poll_done();  
    205. }  
    206.   
    207. void spi_poll_done( void ){  
    208.     //while ( !( rSPSTA0 & 0x01 ) )  
    209.     while ( !( ioread32( r_SPSTA0 ) & 0x01 ) )  
    210.         ;  
    211. }  
    212.   
    213. int adc_release( struct inode *inode, struct file *filp ){  
    214.     adcopen--;  
    215.     module_put( THIS_MODULE );  
    216.       
    217.     return 0 ;  
    218. }  
    219.   
    220. int adc_init_module( void ){  
    221.     int     result;  
    222.     dev_t   dev = 0;  
    223.       
    224.     if ( adc_major ){  
    225.         dev = MKDEV( adc_major, adc_minor );  
    226.         result = register_chrdev_region( dev, adc_nr_devs, "adc" );  
    227.     }else{  
    228.         result = alloc_chrdev_region( &dev, adc_minor, adc_nr_devs, "adc" );  
    229.         adc_major = MAJOR( dev );  
    230.     }  
    231.       
    232.     adc_cdev = cdev_alloc();  
    233.     if ( adc_cdev == NULL ){  
    234.         return -1;  
    235.     }  
    236.       
    237.     if ( result < 0 ){  
    238.         printk( KERN_WARNING "adc: can't get major %d ", adc_major );  
    239.         return result;  
    240.     }  
    241.     printk( KERN_INFO "adc: this major is %d ", adc_major );  
    242.       
    243.     adcopen = 0;  
    244.     adc_cdev->ops = &adc_fops;  
    245.     cdev_init( adc_cdev, &adc_fops );  
    246.     cdev_add( adc_cdev, dev, 1 );  
    247.   
    248.     adc_address_map();  
    249.     adc_spi_init();  
    250.   
    251.     printk( KERN_INFO "***    adc_init() finished    ***  " );  
    252.   
    253.     return 0;  
    254. }  
    255.   
    256. static int adc_open( struct inode *inode, struct file *filp ){  
    257.     if ( adcopen == 0 )  
    258.         adcopen++;  
    259.     else{  
    260.         printk( KERN_ALERT "Another process open the char device " );  
    261.         return -1;  
    262.     }  
    263.       
    264.     try_module_get( THIS_MODULE );  
    265.       
    266.     return 0;  
    267. }  
    268.   
    269. void adc_cleanup_module( void ){  
    270.     dev_t   devno;  
    271.       
    272.     adc_cancel_add_map();  
    273.       
    274.     devno = MKDEV( adc_major, adc_minor );  
    275.     unregister_chrdev_region( devno, adc_nr_devs );  
    276.     cdev_del( adc_cdev );  
    277. }  
    278.   
    279. module_init( adc_init_module );  
    280. module_exit( adc_cleanup_module );  
     

  • 相关阅读:
    Android 内存溢出解决方案(OOM) 整理总结
    浅思OC的语言特性
    netsh winsock reset 11003
    Utility
    百度地图手机四角坐标
    Mysql 导入 MSSQL
    Python import 指定目录中的模块
    POJ:3061-Subsequence(尺取法模板详解)
    POJ:3616-Milking Time
    POJ:2385-Apple Catching(dp经典题)
  • 原文地址:https://www.cnblogs.com/zym0805/p/4847574.html
Copyright © 2011-2022 走看看