ARMLinux driver-ADC Driver (interrupt mode)

Source: Internet
Author: User
Hardware Platform: FL2440 kernel version: 2.6.28 host platform: Ubuntu11.04 kernel version: 2.6.39 this driver has been written for a long time, because the original Linux kernel compiled the touch screen driver into the kernel, while the ADC interrupt in the touch screen driver selects ir1__sample_random as the type during registration, rather than the shared type. Therefore, when the self-written ADC Driver opens each time, the error message is displayed, indicating that the ADC fails to be registered. Solution: reconfigure the kernel

Hardware Platform: FL2440

Kernel version: 2.6.28

Host platform: Ubuntu 11.04

Kernel version: 2.6.39

This driver has been written for a long time, because the touch screen driver was compiled into the kernel during the original Linux kernel compilation, and the ADC interrupt in the touch screen driver was selected during registration.

IRQF_SAMPLE_RANDOM is not a shared type. Therefore, the self-written ADC Driver always prompts that the ADC fails to be registered during each open process.

Solution:

Re-configure the kernel, and select the touch screen driver to compile it in the form of a module instead of directly compiling it into the kernel. In this way, the touch screen driver will not be automatically loaded during Linux Startup. Of course, the IRQ_ADC interrupt number will not be occupied. In this way, you can test your own ADC Driver.

The driver source code is as follows:

  1. # Include
  2. # Include
  3. # Include
  4. # Include /* Create a device node */
  5. # Include
  6. # Include /* Define DECLARE_WAIT_QUEUE_HEAD */
  7. # Include /* Defines irqreturn_t and so on */
  8. # Include /* Request_irq disable_irq enable_irq */
  9. # Include
  10. # Include
  11. # Include/* contains # include "mach/irqs. h "*/
  12. # Include
  13. # Include
  14. # Define ADC_MAJOR 102
  15. # Define ADC_NAME "my_adc"
  16. # Define SUCCESS 0
  17. Static IntAdc_open (StructInode *,StructFile *);
  18. Static IntAdc_release (StructInode *,StructFile *);
  19. Static Int_ Init adc_init (Void);
  20. Static Int_ Exit adc_exit (Void);
  21. StaticSsize_t adc_read (StructFile *,Char*,Size_t, Loff_t *);
  22. VolatileUnsignedLongAdc_con;
  23. UnsignedLongAdc_dat0;
  24. IntFlag;// Wait for the task to complete
  25. UnsignedLongBuf;// Store the converted data
  26. // Declare the waiting queue
  27. DECLARE_WAIT_QUEUE_HEAD (adc_wait );
  28. StructClk * adc_clk;
  29. StaticIrqreturn_t adc_interrupt (IntIrq,Void* Dev_id)// Interrupt handling program
  30. {
  31. If(Flag = 0)
  32. {
  33. Buf = (readw (adc_dat0) & 0x3ff );// Read the converted data
  34. Flag = 1;
  35. Wake_up_interruptible (& adc_wait );// Wake up the process waiting for it
  36. Printk ("Read value is % ld \ n", Buf );
  37. }
  38. ReturnIRQ_HANDLED;
  39. }
  40. StructFile_operations adc_ops =
  41. {
  42. . Owner = THIS_MODULE,
  43. . Read = adc_read,
  44. . Open = adc_open,
  45. . Release = adc_release,
  46. };
  47. Static Int_ Init adc_init (Void)
  48. {
  49. IntRet;
  50. Adc_clk = clk_get (NULL,"Adc");// Get the clock
  51. Clk_enable (adc_clk );// Enable clock
  52. Ret = register_chrdev (ADC_MAJOR, ADC_NAME, & adc_ops );// Register the device
  53. If(Ret <0)
  54. {
  55. Printk ("Register device fail \ n");
  56. ReturnRet;
  57. }
  58. Adc_con = (unsignedLong) Ioremap (0x5821300,4 );
  59. Adc_dat0 = (VolatileUnsignedLong) Ioremap (0x58000000 + S3C2410_ADCDAT0, 4 );
  60. If(! (Adc_con & adc_dat0 ))
  61. {
  62. Printk ("Failed to ioremap \ n");
  63. GotoHandle;
  64. }
  65. Printk ("Initialized... \ n");
  66. ReturnSUCCESS;
  67. Handle:
  68. Unregister_chrdev (ADC_MAJOR, ADC_NAME );
  69. Return-1;
  70. }
  71. Static IntAdc_open (StructInode * inode,StructFile * file)// Enable the device function
  72. {
  73. // Registration interrupted
  74. IntRet;
  75. // Disable_irq (IRQ_ADC );
  76. // Enable_irq (IRQ_ADC );
  77. Ret = request_irq (IRQ_ADC, adc_interrupt, ir1__shared, ADC_NAME, 1 );// Registration interrupt IRQ_ADC defined in mach/irqs. h
  78. If(Ret <0)
  79. {
  80. Printk ("IRQ % d can not request \ n", IRQ_ADC );
  81. ReturnRet;
  82. }
  83. ReturnSUCCESS;
  84. }
  85. Static IntAdc_release (StructInode * inode,StructFile * file)// Disable the device function
  86. {
  87. Free_irq (IRQ_ADC, 1 );// Release interrupted
  88. ReturnSUCCESS;
  89. }
  90. StaticSsize_t adc_read (StructFile * file,
  91. Char* Buffer,
  92. Size_tLength,
  93. Loff_t * offset)// Device read Function
  94. {
  95. Writew (1 <14) | (0x31 <6), adc_con );// Set ADCCON
  96. Writew (readw (adc_con) | 0x1), adc_con );// Start ad ing
  97. Wait_event_interruptible (adc_wait, flag );
  98. Flag = 0;
  99. }
  100. Static Int_ Exit adc_exit (Void)// Driver uninstall Function
  101. {
  102. Iounmap (adc_con );
  103. Iounmap (adc_dat0 );
  104. Unregister_chrdev (ADC_MAJOR, ADC_NAME );
  105. Clk_disable (adc_clk );
  106. Clk_put (adc_clk );
  107. Printk ("The adc is unintialized \ n");
  108. ReturnSUCCESS;
  109. }
  110. Module_init (adc_init );
  111. Module_exit (adc_exit );
  112. MODULE_LICENSE ("GPL");

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.