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:
- # Include
- # Include
- # Include
- # Include /* Create a device node */
- # Include
- # Include /* Define DECLARE_WAIT_QUEUE_HEAD */
- # Include /* Defines irqreturn_t and so on */
- # Include /* Request_irq disable_irq enable_irq */
- # Include
- # Include
- # Include/* contains # include "mach/irqs. h "*/
- # Include
- # Include
- # Define ADC_MAJOR 102
- # Define ADC_NAME "my_adc"
- # Define SUCCESS 0
- Static IntAdc_open (StructInode *,StructFile *);
- Static IntAdc_release (StructInode *,StructFile *);
- Static Int_ Init adc_init (Void);
- Static Int_ Exit adc_exit (Void);
- StaticSsize_t adc_read (StructFile *,Char*,Size_t, Loff_t *);
- VolatileUnsignedLongAdc_con;
- UnsignedLongAdc_dat0;
- IntFlag;// Wait for the task to complete
- UnsignedLongBuf;// Store the converted data
- // Declare the waiting queue
- DECLARE_WAIT_QUEUE_HEAD (adc_wait );
- StructClk * adc_clk;
- StaticIrqreturn_t adc_interrupt (IntIrq,Void* Dev_id)// Interrupt handling program
- {
- If(Flag = 0)
- {
- Buf = (readw (adc_dat0) & 0x3ff );// Read the converted data
- Flag = 1;
- Wake_up_interruptible (& adc_wait );// Wake up the process waiting for it
- Printk ("Read value is % ld \ n", Buf );
- }
- ReturnIRQ_HANDLED;
- }
- StructFile_operations adc_ops =
- {
- . Owner = THIS_MODULE,
- . Read = adc_read,
- . Open = adc_open,
- . Release = adc_release,
- };
- Static Int_ Init adc_init (Void)
- {
- IntRet;
- Adc_clk = clk_get (NULL,"Adc");// Get the clock
- Clk_enable (adc_clk );// Enable clock
- Ret = register_chrdev (ADC_MAJOR, ADC_NAME, & adc_ops );// Register the device
- If(Ret <0)
- {
- Printk ("Register device fail \ n");
- ReturnRet;
- }
- Adc_con = (unsignedLong) Ioremap (0x5821300,4 );
- Adc_dat0 = (VolatileUnsignedLong) Ioremap (0x58000000 + S3C2410_ADCDAT0, 4 );
- If(! (Adc_con & adc_dat0 ))
- {
- Printk ("Failed to ioremap \ n");
- GotoHandle;
- }
- Printk ("Initialized... \ n");
- ReturnSUCCESS;
- Handle:
- Unregister_chrdev (ADC_MAJOR, ADC_NAME );
- Return-1;
- }
- Static IntAdc_open (StructInode * inode,StructFile * file)// Enable the device function
- {
- // Registration interrupted
- IntRet;
- // Disable_irq (IRQ_ADC );
- // Enable_irq (IRQ_ADC );
- Ret = request_irq (IRQ_ADC, adc_interrupt, ir1__shared, ADC_NAME, 1 );// Registration interrupt IRQ_ADC defined in mach/irqs. h
- If(Ret <0)
- {
- Printk ("IRQ % d can not request \ n", IRQ_ADC );
- ReturnRet;
- }
- ReturnSUCCESS;
- }
- Static IntAdc_release (StructInode * inode,StructFile * file)// Disable the device function
- {
- Free_irq (IRQ_ADC, 1 );// Release interrupted
- ReturnSUCCESS;
- }
- StaticSsize_t adc_read (StructFile * file,
- Char* Buffer,
- Size_tLength,
- Loff_t * offset)// Device read Function
- {
- Writew (1 <14) | (0x31 <6), adc_con );// Set ADCCON
- Writew (readw (adc_con) | 0x1), adc_con );// Start ad ing
- Wait_event_interruptible (adc_wait, flag );
- Flag = 0;
- }
- Static Int_ Exit adc_exit (Void)// Driver uninstall Function
- {
- Iounmap (adc_con );
- Iounmap (adc_dat0 );
- Unregister_chrdev (ADC_MAJOR, ADC_NAME );
- Clk_disable (adc_clk );
- Clk_put (adc_clk );
- Printk ("The adc is unintialized \ n");
- ReturnSUCCESS;
- }
- Module_init (adc_init );
- Module_exit (adc_exit );
- MODULE_LICENSE ("GPL");