sam9260 adc module

  1. /*  
  2.  * driver/char/at91_adc.c  
  3.  *  
  4.  * Copyright (C) 2007 Embedall Technology Co., Ltd.  
  5.  *  
  6.  * Analog-to-digital Converter(ADC) Driver.  
  7.  *  
  8.  * This program is free software; you can redistribute it and/or modify  
  9.  * it under the terms of the GNU General Public License as published by  
  10.  * the Free Software Foundation; either version 2 of the License, or  
  11.  * (at your option) any later version.  
  12.  */   
  13.    
  14. #include <linux/types.h>   
  15. #include <linux/init.h>   
  16. #include <linux/kernel.h>   
  17. #include <linux/module.h>   
  18. #include <linux/version.h>   
  19. #include <linux/spinlock.h>   
  20. #include <linux/interrupt.h>   
  21. #include <linux/platform_device.h>   
  22. #include <linux/cdev.h>   
  23. #include <linux/fs.h>   
  24. #include <linux/ioctl.h>   
  25. #include <linux/poll.h>   
  26.    
  27. #include <linux/at91_adc.h>   
  28.    
  29. #include <asm/arch/hardware.h>   
  30. #include <asm/arch/gpio.h>   
  31. #include <asm/arch/at91_adc.h>   
  32. #include <asm/arch/at91_tc.h>   
  33. #include <asm/arch/at91_pmc.h>   
  34.    
  35.    
  36.    
  37.    
  38. #define DRV_NAME "at91_adc"   
  39. #define DEV_NAME "adc0"   
  40.    
  41. #define adc_readl(adc,reg)     (__raw_readl((adc)->membase + (reg)))   
  42. #define adc_writel(adc,reg,v)  (__raw_writel((v), (adc)->membase + (reg)))   
  43. #define tc_readl(adc,reg)      (__raw_readl((adc)->tcxbase + (reg)))   
  44. #define tc_writel(adc,reg,v)   (__raw_writel((v), (adc)->tcxbase + (reg)))   
  45.    
  46.    
  47. #define ADC_MAX_CHANNEL CONFIG_AT91_ADC_CHANNELS   
  48. #define BUF_SIZE        8   
  49.    
  50. //#define buf_cnt(channel) (((channel)->head - (channel)->tail) & ((BUF_SIZE)-1))   
  51. //#define buf_space(channel) (((channel)->tail-((channel)->head+1))&(BUF_SIZE-1))   
  52.    
  53. struct adc;   
  54.    
  55. static int minor_num = 0;   
  56. static int major_num = 0;   
  57. struct adc_channel    
  58. {   
  59.     struct cdev         cdev;   
  60.     struct device       *dev;   
  61.     struct class_device *class_dev;   
  62.        
  63.     int id;   
  64.     int adc_data;   
  65.     int head;   
  66.     int tail;   
  67.        
  68.     struct fasync_struct *fasync;   
  69.     struct adc *adc;   
  70. };   
  71.    
  72. struct adc   
  73. {   
  74.     dev_t           devt;   
  75.     struct class    *class;   
  76.     void __iomem    *membase;   
  77.     void __iomem    *tcbbase;   
  78.     void __iomem    *tcxbase;   
  79.     unsigned int    irq;   
  80.     struct adc_mode mode;   
  81.    
  82.     spinlock_t      lock;   
  83.    
  84.     struct adc_channel *channel[ADC_MAX_CHANNEL];   
  85. };   
  86.    
  87.    
  88. static struct adc *adc;   
  89.    
  90. static inline int buf_in(struct adc_channel *channel, int v)   
  91. {   
  92.     channel->adc_data = v;   
  93.     //channel->head = (channel->head + 1) & (BUF_SIZE - 1);   
  94.     return channel->adc_data;   
  95. }   
  96.    
  97. static int adc_init_tc(struct adc *adc)   
  98. {   
  99.     unsigned int dummy = 0;   
  100.    
  101.     spin_lock(&adc->lock);   
  102.        
  103.     if (adc->mode.trigger != ADC_TRIGGER_TIMER) {   
  104.         at91_sys_write(AT91_PMC_PCDR, 1 << AT91SAM9260_ID_TC2);   
  105.         spin_unlock(&adc->lock);   
  106.         return 0;   
  107.     }   
  108.        
  109.     tc_writel(adc, AT91_TC_CCR, AT91_TC_CLKDIS);   
  110.        
  111.     dummy |= (AT91_TC_TIMER_CLOCK5 | AT91_TC_CPCTRG | AT91_TC_WAVE |   
  112.           AT91_TC_WAVESEL_UP_AUTO | AT91_TC_ACPA_SET |   
  113.           AT91_TC_ACPC_CLEAR );   
  114.     tc_writel(adc, AT91_TC_CMR, dummy);   
  115.        
  116.     if (adc->mode.trigger_time) {   
  117.         dummy = (adc->mode.trigger_time*1000000)/(1000000000/32768);   
  118.         if (dummy > 0xffff) dummy = 0xffff;   
  119.         tc_writel(adc, AT91_TC_RC, dummy);   
  120.         tc_writel(adc, AT91_TC_RA, dummy * 3 / 5);   
  121.     } else {   
  122.         tc_writel(adc, AT91_TC_RC, 32768);   
  123.         tc_writel(adc, AT91_TC_RA, 32768 * 3 / 5);   
  124.     }   
  125.        
  126.     at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_TC2);   
  127.     tc_writel(adc, AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG);   
  128.     spin_unlock(&adc->lock);   
  129.     return 0;   
  130. }   
  131.    
  132. static int adc_hw_init(struct adc *adc)   
  133. {   
  134.     adc_writel(adc, AT91_ADC_CR,  AT91_ADC_SWRST);   
  135.     adc_writel(adc, AT91_ADC_IER, AT91_ADC_DRDY);   
  136.     at91_sys_write(AT91_PMC_PCER, 1 << adc->irq);   
  137.     return 0;   
  138. }   
  139.    
  140. static int adc_fasync(int fd, struct file *file, int mode)   
  141. {   
  142.     struct adc_channel *channel = file->private_data;   
  143.     return fasync_helper(fd, file, mode, &channel->fasync);   
  144. }   
  145.    
  146. static int adc_open(struct inode *inode, struct file *file)   
  147. {   
  148.     struct adc *adc;   
  149.     struct adc_channel *channel;   
  150.     channel = container_of(inode->i_cdev, struct adc_channel, cdev);   
  151.     file->private_data = channel;   
  152.     adc = channel->adc;   
  153.    
  154.     spin_lock(&adc->lock);   
  155.     at91_set_multi_drive(PIN_BASE + 0x40 + channel->id, 1);   
  156.     adc_writel(adc, AT91_ADC_IER,  (1 << channel->id));   
  157.     adc_writel(adc, AT91_ADC_CHER, (1 << channel->id));   
  158.     spin_unlock(&adc->lock);   
  159.        
  160.     return nonseekable_open(inode, file);   
  161. }   
  162.    
  163. static int adc_release(struct inode *inode, struct file *file)   
  164. {   
  165.     struct adc *adc;   
  166.     struct adc_channel *channel;   
  167.     channel = container_of(inode->i_cdev, struct adc_channel, cdev);   
  168.     adc = channel->adc;   
  169.        
  170. //  adc_fasync(-1, file, 0);   
  171.    
  172.     spin_lock(&adc->lock);   
  173.     adc_writel(adc, AT91_ADC_IDR,  1 << channel->id);   
  174.     adc_writel(adc, AT91_ADC_CHDR, 1 << channel->id);   
  175.     spin_unlock(&adc->lock);   
  176.        
  177.     return 0;   
  178. }   
  179.    
  180. static ssize_t adc_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)   
  181. {   
  182.     return 0;   
  183. }   
  184.    
  185. static ssize_t adc_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)   
  186. {   
  187.     return 0;   
  188. }   
  189.    
  190. /* static void adc_sigio(struct adc_channel *channel) */   
  191. /* { */   
  192. /*  if (channel->fasync) */   
  193. /*      kill_fasync(&channel->fasync, SIGIO, POLL_IN); */   
  194. /* } */   
  195.    
  196. static int adc_ioctl(struct inode *inode, struct file *file,   
  197.              unsigned int cmd, unsigned long arg)   
  198. {   
  199.     struct adc *adc;   
  200.     struct adc_channel *channel;   
  201.     struct adc_mode *mode;   
  202.    
  203.     int ret = 0;   
  204.     unsigned int dummy = 0;   
  205.        
  206.     void __user *argp = (void __user *)arg;   
  207.     int __user *p = argp;   
  208.        
  209.     channel = container_of(inode->i_cdev, struct adc_channel, cdev);   
  210.     adc = channel->adc;   
  211.     mode = &adc->mode;   
  212.        
  213.     switch (cmd) {   
  214.     case ADCCTL_RESET:   
  215.         adc_writel(adc, AT91_ADC_CR, AT91_ADC_SWRST);   
  216.         return 0;   
  217.     case ADCCTL_START:   
  218.         adc_writel(adc, AT91_ADC_CR, AT91_ADC_START);   
  219.         return 0;   
  220.     case ADCCTL_SETMODE:   
  221.         ret = copy_from_user(mode, argp, sizeof(struct adc_mode));   
  222.            
  223.         if (mode->trigger == ADC_TRIGGER_TIMER)   
  224.             dummy |= AT91_ADC_TRGEN | AT91_ADC_TRGSEL_TC2;   
  225.         else if (mode->trigger == ADC_TRIGGER_EXT)   
  226.             dummy |= AT91_ADC_TRGEN | AT91_ADC_TRGSEL_EXT;   
  227.         if (mode->resolution & ADC_M_8BIT)   
  228.             dummy |= AT91_ADC_LOWRES;   
  229.         if (mode->sleep_mode)   
  230.             dummy |= AT91_ADC_SLEEP;   
  231.         if (mode->adc_clock)   
  232.             dummy |= AT91_ADC_PRESCAL_(mode->adc_clock);   
  233.         if (mode->startup_time)   
  234.             dummy |= AT91_ADC_STARTUP_(mode->startup_time);   
  235.         if (mode->sample_time)   
  236.             dummy |= AT91_ADC_SHTIM_(mode->sample_time);   
  237.         adc_init_tc(adc);   
  238.         spin_lock(&adc->lock);   
  239.         adc_writel(adc, AT91_ADC_MR, dummy);   
  240.         spin_unlock(&adc->lock);   
  241.         return 0;   
  242.     case ADCCTL_GETMODE:   
  243.         ret = copy_to_user(argp, mode, sizeof(struct adc_mode));   
  244.         return 0;   
  245.     case ADCCTL_GETDATA:   
  246. //      ret = buf_cnt(channel);   
  247.     //  if (ret > 0) {   
  248.         //  if (!put_user(channel->buf[channel->tail], p))   
  249.             //  channel->tail = (channel->tail + 1) & (BUF_SIZE -1);   
  250.             //return 0;   
  251.         //}   
  252.          put_user(channel->adc_data,p);   
  253.         return -EFAULT;   
  254. //  case ADCCTL_GETCNT:   
  255.     //  return put_user(buf_cnt(channel), p);   
  256.     case ADCCTL_GETSTATUS:   
  257.         return put_user(adc_readl(adc, AT91_ADC_SR), p);   
  258.     default:   
  259.         return -EINVAL;   
  260.     }   
  261.     return -EINVAL;   
  262. }   
  263.    
  264. static struct file_operations adc_fops = {   
  265.         .owner     = THIS_MODULE,   
  266.         .read      = adc_read,   
  267.         .write     = adc_write,   
  268.         .open      = adc_open,   
  269.         .release   = adc_release,   
  270.     .ioctl     = adc_ioctl,   
  271.         .fasync    = adc_fasync,   
  272. };   
  273.            
  274. static irqreturn_t adc_interrupt(int irq, void *dev_id)   
  275. {   
  276.     struct adc *adc = dev_id;   
  277.     struct adc_channel *channel;   
  278.        
  279.    
  280.     unsigned int status;   
  281.    
  282.     status = adc_readl(adc, AT91_ADC_SR) & adc_readl(adc, AT91_ADC_IMR);   
  283.     while (status) {   
  284.         printk(KERN_DEBUG "at91_adc: interrupt status reg 0x%08x\n",   
  285.                status);   
  286.            
  287.         if (status & AT91_ADC_EOC0){   
  288.             channel = adc->channel[0];   
  289.             buf_in(channel, adc_readl(adc, AT91_ADC_CDR0));   
  290.              printk(KERN_INFO "the adc_data is %d\n",channel->adc_data);   
  291. //          adc_sigio(channel);   
  292.         }   
  293.         if (status & AT91_ADC_EOC1){   
  294.             channel = adc->channel[1];   
  295.             buf_in(channel, adc_readl(adc, AT91_ADC_CDR1));   
  296.             printk(KERN_INFO "the adc_data is %d\n",channel->adc_data);   
  297. //          adc_sigio(channel);   
  298.         }   
  299.         if (status & AT91_ADC_EOC2){   
  300.             channel = adc->channel[2];   
  301.             buf_in(channel, adc_readl(adc, AT91_ADC_CDR2));   
  302.             printk(KERN_INFO "the adc_data is %d\n",channel->adc_data);   
  303. //          adc_sigio(channel);   
  304.         }   
  305.         if (status & AT91_ADC_EOC3) {   
  306.             channel = adc->channel[3];   
  307.             buf_in(channel, adc_readl(adc, AT91_ADC_CDR3));   
  308.             printk(KERN_INFO "the adc_data is %d\n",channel->adc_data);   
  309. //          adc_sigio(channel);   
  310.         }   
  311.         if (status & AT91_ADC_DRDY)   
  312.             adc_readl(adc, AT91_ADC_LCDR);   
  313.            
  314.         status = adc_readl(adc, AT91_ADC_SR) & adc_readl(adc, AT91_ADC_IMR);   
  315.     }   
  316.     return IRQ_HANDLED;   
  317. }   
  318.    
  319. static int __exit adc_remove(struct platform_device *pdev)   
  320. {   
  321.     struct adc_channel *channel = platform_get_drvdata(pdev);   
  322.        
  323.     class_device_unregister(channel->class_dev);   
  324.     cdev_del(&channel->cdev);   
  325.     kfree(channel);   
  326.     return 0;   
  327. }   
  328. static struct platform_device adc_channel_device[ADC_MAX_CHANNEL];   
  329. /*  
  330. static int __init adc_add_channel_device(void)  
  331. {  
  332.     int i;  
  333.   
  334.     for (i=0; i<ADC_MAX_CHANNEL; i++){  
  335.         adc_channel_device[i].name = DRV_NAME;  
  336.         adc_channel_device[i].id   = i;  
  337.         platform_device_register(&adc_channel_device[i]);  
  338.     }  
  339.     return 0;  
  340. }  
  341. */   
  342.    
  343. static int __init adc_init(void)   
  344. {struct adc_channel *channel;   
  345.    
  346.     int ret = 0;   
  347.     //struct adc_channel *channel;   
  348.     int ret1;     
  349.     adc = kmalloc(sizeof(struct adc), GFP_KERNEL);   
  350.     if (!adc)   
  351.         return -ENOMEM;   
  352.    
  353.     if (!request_mem_region(AT91SAM9260_BASE_ADC, SZ_16K, DRV_NAME)){   
  354.         kfree(adc);   
  355.         return -EBUSY;   
  356.     }   
  357.     adc->membase = ioremap(AT91SAM9260_BASE_ADC, SZ_16K);   
  358.     if (adc->membase == NULL)   
  359.         goto adc_release_mem;   
  360.    
  361.     if (!request_mem_region(AT91SAM9260_BASE_TC0, SZ_16K, DRV_NAME))   
  362.         goto adc_iounmap;   
  363.     adc->tcbbase = ioremap(AT91SAM9260_BASE_TC0, SZ_16K);   
  364.     if (adc->tcbbase == NULL)   
  365.         goto adc_release_mem_tc;   
  366.    
  367.     adc->irq = AT91SAM9260_ID_ADC;   
  368.     adc->tcxbase = adc->tcbbase + 0x80;   
  369.     spin_lock_init(&adc->lock);   
  370.        
  371.     adc->class = class_create(THIS_MODULE, DEV_NAME);   
  372.     if (IS_ERR(adc->class)){   
  373.         printk(KERN_ERR "at91_adc: faile to create device class\n");   
  374.         goto adc_iounmap_tc;   
  375.     }   
  376.        
  377.     ret = alloc_chrdev_region(&adc->devt, 0, 1, DEV_NAME);   
  378.     if (ret < 0) {   
  379.         printk(KERN_ERR"%s: failed to allocate dev region\n", __FILE__);   
  380.         goto adc_destroy_class;   
  381.     }   
  382.    
  383.     if (request_irq(adc->irq, adc_interrupt, IRQF_SHARED, DRV_NAME, adc)){   
  384.         printk(KERN_ERR"%s: request irq failed\n", __FILE__);   
  385.         goto adc_del_channel;   
  386.     }   
  387.        
  388.     adc_hw_init(adc);   
  389.         printk(KERN_INFO "&&123456xx\n");   
  390.     //platform_driver_register(&adc_driver);   
  391.     printk(KERN_INFO "Analog-to-Digital Converter (irq %d)\n", adc->irq);   
  392.        
  393. //  adc_add_channel_device();   
  394.        
  395.    
  396.         printk(KERN_ERR "&&123456&&\n");   
  397.     channel = kmalloc(sizeof(struct adc_channel), GFP_KERNEL);   
  398.     if (!channel){   
  399.       printk(KERN_ERR "&&123456&&\n");       
  400.         //printk(KERN_ERR "at91_adc: failed to kmalloc channel %d\n", pdev->id);   
  401.         return -ENOMEM;   
  402.     }   
  403. //  channel->fasync = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);   
  404. //  if (!channel->fasync) return -ENOMEM;   
  405.     channel->id  = 0;   
  406.     //channel->dev = &pdev->dev;   
  407.     channel->adc = adc;   
  408.     channel->head = 0;   
  409.     channel->tail = 0;   
  410.        
  411.     cdev_init(&channel->cdev, &adc_fops);   
  412.     channel->cdev.owner = THIS_MODULE;   
  413.     ret1 = cdev_add(&channel->cdev, MKDEV(MAJOR(adc->devt), channel->id), 1);   
  414.     if (ret1) {   
  415.         //printk(KERN_ERR "at91_adc: failed to add channel %d device\n", pdev->id);   
  416.            
  417.         kfree(channel);   
  418.         return ret1;   
  419.     }   
  420.     channel->class_dev = class_device_create(adc->class, NULL,   
  421.                          MKDEV(MAJOR(adc->devt),   
  422.                                channel->id),   
  423.                          NULL,   
  424.                          DEV_NAME);   
  425.     if (IS_ERR(channel->class_dev)) {   
  426.         cdev_del(&channel->cdev);   
  427.         kfree(channel);   
  428.         return PTR_ERR(channel->class_dev);   
  429.     }   
  430.    
  431.     adc->channel[channel->id] = channel;   
  432.     //platform_set_drvdata(pdev, channel);   
  433.    
  434.     printk(KERN_INFO "at91_adc. major  is %d\n",   
  435.            MAJOR(adc->devt));   
  436.        
  437.     return 0;   
  438.            
  439. adc_del_channel:   
  440.     unregister_chrdev_region(adc->devt, 1);   
  441. adc_destroy_class:   
  442.     class_destroy(adc->class);   
  443. adc_iounmap_tc:   
  444.     iounmap(adc->tcbbase);   
  445. adc_release_mem_tc:   
  446.     release_mem_region(AT91SAM9260_BASE_TC0, SZ_16K);   
  447. adc_iounmap:   
  448.     iounmap(adc->membase);   
  449. adc_release_mem:   
  450.     release_mem_region(AT91SAM9260_BASE_ADC, SZ_16K);   
  451.     kfree(adc);   
  452.     return ret;   
  453. }   
  454.    
  455.            
  456. static void __exit adc_exit(void)   
  457. {   
  458.     //platform_driver_unregister(&adc_driver);   
  459.     unregister_chrdev_region(adc->devt, ADC_MAX_CHANNEL);   
  460.     class_destroy(adc->class);   
  461.     free_irq(adc->irq, adc);   
  462.     iounmap(adc->tcbbase);   
  463.     release_mem_region(AT91SAM9260_BASE_TC0, SZ_16K);   
  464.     iounmap(adc->membase);   
  465.     release_mem_region(AT91SAM9260_BASE_ADC, SZ_16K);   
  466.     kfree(adc);   
  467. }   
  468.    
  469.    
  470. module_init(adc_init);   
  471. module_exit(adc_exit);   
  472.    
  473. MODULE_AUTHOR("jiang ming bo ");   
  474. MODULE_LICENSE("GPL");   
  475. MODULE_DESCRIPTION("AT91 Analog-to-Digital Converter Driver");   
  476.    
 

posted on 2016-09-12 09:44  嵌入式操作系统  阅读(264)  评论(0编辑  收藏  举报

导航