#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GSC3280_SET_GPIO_REG_BIT(reg) do {\ unsigned int reg_val = 0;\ reg_val = __raw_readl((volatile unsigned int *)(reg));\ reg_val |= (0x01 << tgpios[0].gpio);\ __raw_writel(reg_val, (volatile unsigned int *)(reg));\ } while (0) #define GSC3280_CLR_GPIO_REG_BIT(reg) do {\ unsigned int reg_val = 0;\ reg_val = __raw_readl((volatile unsigned int *)(reg));\ reg_val &= ~(0x01 << tgpios[0].gpio);\ __raw_writel(reg_val, (volatile unsigned int *)(reg));\ } while (0) enum{ TGPIO, //GPIO23 TGPIO_MAX_PIN_NR }; struct gpio tgpios[TGPIO_MAX_PIN_NR] = { {GSC3280_GPA(29), GPIOF_IN, "GPIO"}, }; struct tgpio { struct cdev cdev; struct gpio *tgpio; struct class *tgpio_class; dev_t dev; struct mutex t_lock; }; struct tgpio tgpio_priv; int test() { printk(KERN_INFO "Do something !\n"); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTEN); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_PORTA_EOI); GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTMASK); return 0; } irqreturn_t tgpio_isr ( int irq, void * dev_id ) { if(*(volatile unsigned int*)0xbc110040 & 1 << 29) //GPIO29 { printk(KERN_INFO "in vuart_isr\n"); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTMASK); GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTEN); test(); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_PORTA_EOI); } return IRQ_HANDLED; } static int tgpio_open(struct inode *inode, struct file *filp) { return 0; } static int tgpio_release(struct inode *inode, struct file *filp) { return 0; } void tgpio_gpio_ctrl(void) { #if 0 //边沿触发 GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTTYPE_LEVEL); //GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTTYPE_LEVEL); #endif // GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTTYPE_LEVEL); GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INT_POLARITY); GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INT_POLARITY); //去毛刺 GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_DEBOUNCE); //不屏蔽该中断 GSC3280_CLR_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTMASK); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_INTEN); GSC3280_SET_GPIO_REG_BIT(GSC3280_REGADDR_GPIO_PORTA_EOI); } struct file_operations tgpio_fops = { .owner = THIS_MODULE, .open = tgpio_open, .release = tgpio_release, }; static int __init tgpio_init(void) { int err,ret; int result; int major; int p_irq; printk(KERN_INFO "test gpio init \n"); result = alloc_chrdev_region(&tgpio_priv.dev, 0, 0, "tgpio"); major = MAJOR(tgpio_priv.dev); if (result < 0) { printk(KERN_WARNING "vuart: can't get major %d\n", major); return result; } cdev_init(&tgpio_priv.cdev, &tgpio_fops); tgpio_priv.cdev.owner = THIS_MODULE; tgpio_priv.cdev.ops = &tgpio_fops; err = cdev_add(&tgpio_priv.cdev, tgpio_priv.dev, 1); if (err) { printk(KERN_NOTICE "Error[%d] cdev_add .\n", err); return -1; } tgpio_priv.tgpio_class = class_create(THIS_MODULE, "tgpio"); if (IS_ERR(tgpio_priv.tgpio_class)) { printk(KERN_ERR "Failed in create vuart_cdev class\n"); return -1; } device_create(tgpio_priv.tgpio_class, NULL, tgpio_priv.dev, NULL, "tgpio"); p_irq = gpio_to_irq(tgpios[TGPIO].gpio); ret = gpio_request_array(tgpios, TGPIO_MAX_PIN_NR); if (ret < 0) { printk(KERN_INFO "GPIO request error \n"); } tgpio_priv.tgpio = tgpios; err = request_irq(p_irq, &tgpio_isr, IRQF_SHARED, "gsc3280-gpio", &tgpio_priv); if (err < 0) { printk(KERN_ERR "test_gpio request_irq[%d] failed!\n", p_irq); err = -ENODEV; goto FREE_GPIO; } tgpio_gpio_ctrl(); return 0; FREE_GPIO: gpio_free_array(tgpios, TGPIO_MAX_PIN_NR); return err; } static void __exit tgpio_exit(void) { int p_irq; p_irq = gpio_to_irq(tgpios[TGPIO].gpio); free_irq(p_irq, &tgpios[TGPIO]); gpio_free_array(tgpios, TGPIO_MAX_PIN_NR); cdev_del(&tgpio_priv.cdev); unregister_chrdev_region(tgpio_priv.dev, 1); device_destroy(tgpio_priv.tgpio_class, tgpio_priv.dev); class_destroy(tgpio_priv.tgpio_class); } module_init(tgpio_init); module_exit(tgpio_exit); MODULE_AUTHOR("songxingjia@china-cpu.com"); MODULE_DESCRIPTION("GSC3280 INTERRUPT GPIO Driver"); MODULE_LICENSE("GPL");