Kernel2.6.32.2mini2440led driver interrupt (dejitter) Processing

Source: Internet
Author: User
# Define delinuxmodule. h # define delinuxinit. h # define delinuxmm. h # define delinuxslab. h # define delinuxtypes. h # define delinuxsemaphore. h # define delinuxcdev. h # define delinuxfs. h # define delinuxsemaphore. h # define delinuxirq. h # includeasm

# Include linux/module. h # include linux/init. h # include linux/mm. h # include linux/slab. h # include linux/types. h # include linux/semaphore. h # include linux/cdev. h # include linux/fs. h # include linux/semaphore. h # include linux/irq. h # include asm

# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include

# Include
# Include
# Include

# Define LED_MAJOR 250
# Define LED_NAME "leds"

# Define KEY_COUNT 4
# Define KEY_DELAY HZ/50

DECLARE_WAIT_QUEUE_HEAD (r_wait); // initialize the waiting queue
// Wait_queue_head_t r_wait;
// Init_waitqueue_head (& r_wait );
Static struct timer_list key_timers [KEY_COUNT]; // defines the timer.
Static volatile bool ide.pdf;

Static void buttons_timer (unsigned long );

Static unsigned long led_table [] = {
S3C2410_GPB (5 ),
S3C2410_GPB (6 ),
S3C2410_GPB (7 ),
S3C2410_GPB (8 ),
}; // Bit address

Static unsigned int led_cfg_table [] = {
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
}; // The led is the input

Struct button_irq_key {
Int irq;
Int pin;
Unsigned long flags;
Char * name;
};

Static struct button_irq_key button_irqs [] = {
{IRQ_EINT8, S3C2410_GPG (0), ir1__trigger_falling, "key1 "},
{IRQ_EINT11, S3C2410_GPG (3), ir1__trigger_falling, "key2 "},
{IRQ_EINT13, S3C2410_GPG (5), ir1__trigger_falling, "key3 "},
{IRQ_EINT14, S3C2410_GPG (6), ir1__trigger_falling, "key4 "},
};

Static volatile int press_cnt [] = {0, 0, 0 };
Static volatile int pressed = 0;


Struct leds_cdev
{
Struct cdev;
Struct semaphore sem;
};

Int leds_major = LED_MAJOR;
Struct leds_cdev dev;

Static irqreturn_t buttons_interrupt (int irq, void * dev_id) // key Interrupt Processing Function
{
// Volatile int * press_count = (volatile int *) dev_id;

// Disable_irq (irq );
Int key = 0;

Switch (irq ){
Case 52:
Key = 0;
Break;
Case 55:
Key = 1;
Break;
Case 57:
Key = 2;
Break;
Case 58:
Key = 3;
Break;
Default: break;

}

Key_timers [key]. data = key;
Mod_timer (& key_timers [key], jiffies + KEY_DELAY );
Printk (KERN_EMERG "irq success ");
Return IRQ_HANDLED;
}


Static void buttons_timer (unsigned long arg) // The timer interrupt processing function, deshake implementation
{
Int key = arg;
Int condition;
Int nf;
Condition = s3c2410_gpio_getpin (button_irqs [key]. pin );
If (! Condition)
{
While (! S3c2410_gpio_getpin (button_irqs [key]. pin ));

Key_timers [key]. expires = jiffies + KEY_DELAY;
Add_timer (& key_timers [key]);
Ide.pdf = 1;

Printk (KERN_EMERG "lower is appear ");
} Else {

If (! Ide.pdf)
Return;

Press_cnt [key] + = 1;
Nf = press_cnt [key] % 2;
S3c2410_gpio_setpin (led_table [key], nf );

Pressed = 1;
Wake_up_interruptible (& r_wait );
Ide.pdf = 0;

Printk (KERN_EMERG "up is appear % d", nf );
// Enable_irq (button_irqs [key]. irq );
}

// Printk (KERN_EMERG "success of interruptible ");
}

Static int led_buttons_open (struct inode * inode, struct file * filp)
{
Int I;
Int err;
For (I = 0; I <sizeof (button_irqs)/sizeof (button_irqs [0]); I ++ ){
Err = request_irq (button_irqs [I]. irq, buttons_interrupt,
Button_irqs [I]. flags, button_irqs [I]. name, (void *) & press_cnt [I]); // request interruption
If (err)
Break;
/* Init_timer (& key_timers [I]);
Key_timers [I]. data = I;
Key_timers [I]. function = buttons_timer;
*/
Setup_timer (& key_timers [I], buttons_timer, I); initialize the timer
}
// Key_timers [0]. expires = jiffies + 3 * HZ;
// Add_timer (& key_timers [0]);
If (err ){
I --;
For (; I> = 0; I --)
Free_irq (button_irqs [I]. irq, (void *) press_cnt [I]);
Return-EBUSY;
}

Return 0;
}

Static ssize_t led_buttons_read (struct file * filp, char _ user * buf, size_t count, loff_t * ppos)
{
Unsigned long err;
Wait_event_interruptible (r_wait, pressed );

Pressed = 0;

Err = copy_to_user (buf, (const void *) press_cnt, sizeof (press_cnt ));
Memset (void *) press_cnt, 0, sizeof (press_cnt ));
Return err? -EFAULT: 0;
}

Static int led_buttons_close (struct inode * inode, struct file * filp)
{
Int I;
For (I = 0; I <sizeof (button_irqs)/sizeof (button_irqs [0]); I ++ ){
Free_irq (button_irqs [I]. irq, (void *) & press_cnt [I]); // release the interrupt number
Del_timer (& key_timers [I]);
}
Return 0;
}

Static int leds_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg)
{
Switch (cmd)
{
Case 0:
If (arg> 4 ){
Return-EINVAL;
}
Down (& dev. sem );
S3c2410_gpio_setpin (led_table [arg], 0 );
Up (& dev. sem );
Return 0;
Case 1:
If (arg> 4 ){
Return-EINVAL;
}
Down (& dev. sem );
S3c2410_gpio_setpin (led_table [arg], 1 );
Up (& dev. sem );
Return 0;
Default:
Return-EINVAL;
}
}

Struct file_operations cdev_fops = {
. Owner = THIS_MODULE,
. Ioctl = leds_ioctl,
. Open = led_buttons_open,
. Read = led_buttons_read,
. Release = led_buttons_close,
};

Static void leds_setup (struct leds_cdev * dev, int index)
{
Int err, devno = MKDEV (leds_major, index );
Cdev_init (& dev-> cdev, & cdev_fops );
Dev-> cdev. owner = THIS_MODULE;
Dev-> cdev. ops = & cdev_fops;
Err = cdev_add (& dev-> cdev, devno, 1 );
If (err)
Printk (KERN_NOTICE "Error % d adding LED % d \ n", err, index );
}

Static int _ init dev_init (void) // module initialization and Registration

{

Int result;
Int I;
// Struct class * my_class;
Dev_t devno = MKDEV (leds_major, 0 );
For (I = 0; I <4; I ++ ){
S3c2410_gpio_cfgpin (led_table [I], led_pai_table [I]);
S3c2410_gpio_setpin (led_table [I], 0 );
}

If (leds_major)
Result = register_chrdev_region (devno, 1, "leds ");
Else {
Result = alloc_chrdev_region (& devno, 0, 1, "leds ");
Leds_major = devno;
}

If (result <0)
Return result;
Leds_setup (& dev, 0 );
Sema_init (& dev. sem, 1 );
/* My_class = class_create (THIS_MODULE, LED_NAME );
If (IS_ERR (my_class ))
{
Printk ("Err: failed in creating class. \ n ");
Return-1;
}
Device_create (my_class, NULL, MKDEV (leds_major, 0), LED_NAME, 0 );
*/
Return 0;

}

Void _ exit dev_exit (void)
{
Cdev_del (& dev. cdev );
Unregister_chrdev_region (MKDEV (leds_major, 0), 1 );
}

Module_init (dev_init );
Module_exit (dev_exit );

MODULE_LICENSE ("GPL ");
MODULE_AUTHOR ("emperor ");

MODULE_DESCRIPTION ("led module ");

Independent Analysis

Pass the test

If there is a BUG, let's look at it and learn from each other through mutual improvement.

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.