⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fkeypad.c

📁 一个在arm linux下的soc的gpio的驱动程序
💻 C
字号:
/* GPIO Push Button driver by ivan wang */
#include <linux/module.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/signal.h>
#include "gpio.h"

static struct proc_dir_entry    *info_entry;
int                             play_c=0;
static pid_t                    mpid;
struct file                     *filp;
spinlock_t                      fgpio_lock;

MODULE_AUTHOR("GM Corp.");
MODULE_LICENSE("GM License");

gpio_params gm;

void fgpio_play_next(void)
{
    printk("Play Next\n");
    /* send signal */
    sys_kill(mpid,SIGUSR1);
}

void fgpio_play_enter(void)
{
    printk("Play Enter\n");
    /* send signal */
    sys_kill(mpid,SIGUSR2);
}

void fgpio_play_switch(void)
{
    printk("Play Switch\n");
    /* send signal */
    sys_kill(mpid,SIGPWR);
}

irqreturn_t gpio_interrupt_handler(int irq, void *dev_id, struct pt_regs *dummy)
{
    //determine which GPIO
    int             gpio_value,i,k;
    unsigned long   flags;

    //printk("in...\n");
    spin_lock_irqsave(&fgpio_lock,flags);

#ifdef CONFIG_PLATFORM_GM8180

        for(i = 0; i <= 50000; i++)
        {
        	k = read_data_input(0,0x36);
        	//if((k&0x3C) != 0x3C)
		//	printk("4 = 0x%x\n",k);
	        if((k & (1 << 1)) == 0)
	        {
	           gpio_value = 2;
	           //printk("K1 is pressed\n");
	           break;
	        }
	        else if((k & (1 << 2)) == 0)
	        {
	           gpio_value = 1;
	           //printk("K2 is pressed\n");
	           break;
	        }
	        else if((k & (1 << 4)) == 0)
	        {
	           gpio_value = 3;
	           //printk("K3 is pressed\n");
	           break;
	        }
	        else if((k & (1 << 5)) == 0)
	        {
	           gpio_value = 4;
	           //printk("K4 is pressed\n");
	           break;
	        }
	}
#elif defined(CONFIG_PLATFORM_GM8185)
        for(i = 0; i <= 50000; i++)
        {
        	k = read_data_input(0,0x10);
        	if((k & (1 << 4)) == 0)
	        {
	           gpio_value = 3;
	           //printk("K3 is pressed\n");
	           break;
	        }
	}	
#elif defined(CONFIG_PLATFORM_GM8120)
        for(k = 8; k <= 11; k++)
        {
            *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE) = ~(1 << k);
//printk("reg 0 = 0x%x, 4 = 0x%x\n",*(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE),*(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x4));
            if(((*(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x4)) & 0x04000) == 0)//k1,k2,k3,k4
            {
                gpio_value = k-8+1;
                printk("int %d\n",gpio_value);
                break;
            }
        }
#endif

    if(gpio_value==1)  //GPIO 1
        fgpio_play_switch();
    else if(gpio_value==2)  //GPIO 2
            fgpio_play_next();
         else if(gpio_value==3)  //GPIO 3
            	fgpio_play_enter();

#ifdef CONFIG_PLATFORM_GM8180
    int_clear(0,0x36);
#elif defined(CONFIG_PLATFORM_GM8185)
    int_clear(0,0x10);    
#else
    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x30)=0xFFFF; //clear interrupt
#endif
    spin_unlock_irqrestore(&fgpio_lock,flags);

    //for compiler optimize issue, must outside spinlock, otherwize do_irq fail

#ifdef CONFIG_PLATFORM_GM8180
    set_int(0,0x36,0x36);
#elif defined(CONFIG_PLATFORM_GM8185)
    set_int(0,0x10,0x10);    
#elif defined(CONFIG_PLATFORM_GM8120)
    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE)=0xF0FF; // enable k1~k4 interrupt
#endif

    return IRQ_HANDLED;
}

static int fgpio_atoi(char *s)
{
    int k = 0;

    k = 0;
    while (*s != '\0' && *s >= '0' && *s <= '9')
    {
        k = 10 * k + (*s - '0');
        s++;
    }
    return k;
}

static int proc_read_gpio_info(char *page, char **start,off_t off, int count,int *eof, void *data)
{
    int     len;
    len=sprintf(page,"%d\n",mpid);
    *eof=1; //end of file
    *start = page + off;
//printk("mpid=%d len:%d off:%d\n",mpid,len,off);
    len=len-off;
    return len;
}

static int proc_write_gpio_info(struct file *file,const char *buffer,unsigned long count, void *data)
{
    int len=count;
    unsigned char value[20];
    if(copy_from_user(value,buffer,len))
        return 0;
    value[len]='\0';
    mpid=fgpio_atoi(value);
//    printk("mpid=%d %s count=%d\n",mpid,value,count);
    return count;
}

static int __init fgpio_init(void)
{
    spin_lock_init(&fgpio_lock);

    mpid=0;

    /* info entry */
    info_entry=create_proc_entry("gpio",777,0);
    if(info_entry==NULL)
    {
        printk("Fail to create proc entry: info!\n");
        return 0;
    }
    info_entry->read_proc=proc_read_gpio_info;
    info_entry->write_proc=proc_write_gpio_info;
    info_entry->owner=THIS_MODULE;
    mpid=0;

#ifdef CONFIG_PLATFORM_GM8180
    gm.group=0;
    gm.int_enable=0x36;
    gm.int_trigger=0;
    gm.int_both=0;
    gm.int_riseneg=0x36;

    set_int(0,0x36,0x36);
    set_data_direct(0,0x36, 0);
    set_int_func(&gm);
#elif defined(CONFIG_PLATFORM_GM8185)    
    gm.group=0;
    gm.int_enable=0x10;
    gm.int_trigger=0;
    gm.int_both=0;
    gm.int_riseneg=0x10;

    set_int(0,0x10,0x10);
    set_data_direct(0,0x10, 0);
    set_int_func(&gm);    
#elif defined(CONFIG_PLATFORM_GM8120)
    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x38)|=0xFF00;

    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x8)|=0x0F00;
    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x20)|=0xFF00;   //enable interrupt
#endif

    if(request_irq(GPIO_FTGPIO010_IRQ, gpio_interrupt_handler, SA_INTERRUPT,"gpio",0) < 0)
        printk(KERN_WARNING "GM GPIO: Unable to allocate IRQ %d\n",GPIO_FTGPIO010_IRQ);
    return 0;
}

static void __exit fgpio_exit(void)
{
#ifdef CONFIG_PLATFORM_GM8180
    set_int(0,0x36,0);
#elif defined(CONFIG_PLATFORM_GM8185)
    set_int(0,0x10,0);    
#else
    *(volatile unsigned int *)(GPIO_FTGPIO010_VA_BASE+0x20) = 0x0000;  //disable interrupt
#endif
	free_irq(GPIO_FTGPIO010_IRQ,0);

    remove_proc_entry("gpio",0);
}

module_init(fgpio_init);
module_exit(fgpio_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -