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

ad7888 linux driver的更多相关文章

  1. Linux driver 板级文件跟踪一般方法

    /*********************************************************************************** * Linux driver ...

  2. OK335xS pwm buzzer Linux driver hacking

    /**************************************************************************** * OK335xS pwm buzzer L ...

  3. linux driver开发

    1 开发linux driver时的调试思路 基本上是打印调试,原因很简单,方便.或者使用工具挂住cpu.

  4. linux driver module

    本文将对Linux系统中的sysfs进行简单的分析,要分析sysfs就必须分析内核的driver-model(驱动模型),两者是紧密联系的.在分析过程中,本文将以platform总线和spi主控制器的 ...

  5. linux driver ------ platform模型,驱动开发分析

    一.platform总线.设备与驱动 在Linux 2.6 的设备驱动模型中,关心总线.设备和驱动3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册 ...

  6. linux driver ------ GPIO的驱动编写和调用

    判断哪些文件被编译进内核: 1.通过 make menuconfig 查看 2.比如查看gpio类型的文件,输入 ls drivers/gpio/*.o,有生成.o文件表示被编译进内核 在编写驱动程序 ...

  7. linux driver ------ platform模型,通过杂项设备(主设备号是10)注册设备节点

    注册完设备和驱动之后,就需要注册设备节点 Linux杂项设备出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费.所以对于这些简单的字符设备它们共 ...

  8. linux driver编译环境搭建和命令

    首先将ubuntu14.04的内核升级到内核3.18.12. 其次,Ubuntu14.04上驱动编译命令 $ sudo make -C ~/linux-3.18.12/ M=`pwd` modules ...

  9. linux driver: input子系统

    <韦东山Linux视频第2期_从零写驱动\第13课第1节 输入子系统概念介绍_P.wmv> 本视频对输入子系统的结构进行了详细的剖析,通过本视频,可以了解到input核心包括了设备和han ...

随机推荐

  1. 解决.NET 调用JAVA WEBService服务中文乱码问题

    主要代码如下: String input ="中文" C#调用代码:  String str = System.Text.Encoding.GetEncoding("UT ...

  2. 想搞机器学习,不会特征工程?你TM逗我那!

    原文:http://dataunion.org/20276.html 作者:JasonDing1354 引言 在之前学习机器学习技术中,很少关注特征工程(Feature Engineering),然而 ...

  3. Lithium: HTML5 响应式的单页面模板

    在线演示:http://www.gbtags.com/gb/demoviewer/2507/837ac02e-4963-46c9-83ee-a0a0bb867f7f/3.-Lithium|app|in ...

  4. C#基础视频教程4.1 如何编写简单的计算器

    要学会基本的窗体控件(button,textbox,label这种,以及他们的重要属性),每个控件的命名要符合规范(例如一般文本框都会重命名txtXXXXX,按钮都会重命名btnXXXXX)   为了 ...

  5. iOS中使用iCloud一些须要注意的地方(Xcode7.2)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 假设认为写的不好请多提意见,假设认为不错请多多支持点赞.谢谢! hopy ;) 在自己的App中怎样使用iCloud有非常多文章能够查阅,这里 ...

  6. Android studio中导入第三方类库

    常常在github上看到一些好用的框架,但是对于一个新手怎样在android studio上导入去总会遇到各种麻烦,索性来研究下第三方类库怎样在android studio上导入. 以我在github ...

  7. Redhat 5禁止IPv6

    Redhat  5禁止IPv6 IPv6还没有全然普及,可是安装完系统之后IPv6是有效的,在一定程度上影响网络性能,所以在我们在全然不使用IPv6的情况下.最好关闭IPv6.如今我们就在本文以完整的 ...

  8. ueditor使用遇到的问题

    1.文件没法上传,需要引入ueditor官网说的那几个jar包才行 2.上传的文件读不出来,路径不对,需要把config.json里面的所有[“”]替换成[/你的项目路径],即把所有的Prefix路径 ...

  9. C# 通过form表单下载文本文件

    public void DownLoadConfigFile(string name) { //获取文件字符串内容 var data = _service.ReadFileStr(_configure ...

  10. 使用maven拆分项目

    在开发环境中,有时需要专人负责专门的模块,其他模块不需接触,这就需要将项目拆分,如下 fund_demo项目具有三个模块,现将主业务core模块单独提出另建一个项目fund_core,拆分时需要注意相 ...