LinkIt Smart MT7688 >> C/C++

Button


drivers/gpio/button/main.c

#include <linux/init.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steward_Fu");
MODULE_DESCRIPTION("MT7688 GPIO Driver");

#define GPIO2_MODE  0x10000064
#define GPIO_CTRL_0 0x10000600
#define GPIO_CTRL_1 0x10000604
#define GPIO_CTRL_2 0x10000608
#define GPIO_DATA_0 0x10000620
#define GPIO_DATA_1 0x10000624
#define GPIO_DATA_2 0x10000628
#define GPIO_DSET_0 0x10000630
#define GPIO_DSET_1 0x10000634
#define GPIO_DSET_2 0x10000638
#define GPIO_DCLR_0 0x10000640
#define GPIO_DCLR_1 0x10000644
#define GPIO_DCLR_2 0x10000648

static volatile unsigned long *gpio2_mode;
static volatile unsigned long *gpio_ctrl_0;
static volatile unsigned long *gpio_ctrl_1;
static volatile unsigned long *gpio_ctrl_2;
static volatile unsigned long *gpio_data_0;
static volatile unsigned long *gpio_data_1;
static volatile unsigned long *gpio_data_2;
static volatile unsigned long *gpio_dset_0;
static volatile unsigned long *gpio_dset_1;
static volatile unsigned long *gpio_dset_2;
static volatile unsigned long *gpio_dclr_0;
static volatile unsigned long *gpio_dclr_1;
static volatile unsigned long *gpio_dclr_2;

static int irq=0;

static irqreturn_t isr_handler(int irq, void *data)
{
  return IRQ_HANDLED;
}

unsigned int mt7688_get(int pin)
{
  uint32_t tmp = 0;

  if(pin <= 31){
    tmp = *gpio_data_0;
    tmp = (tmp >> pin) & 1u;
  }
  else if(pin <= 63){
    tmp = *gpio_data_1;
    tmp = (tmp >> (pin-32)) & 1u;
  } 
  else if(pin <= 95){
    tmp = *gpio_data_2;
    tmp = (tmp >> (pin-64)) & 1u;
  }
  return tmp;
}

void mt7688_dir(int pin, int is_output)
{
  uint32_t tmp;

  if(pin <= 31){
    tmp = *gpio_ctrl_0;
    if(is_output){
      tmp|= (1u << pin);
    }
    else{
      tmp&= ~(1u << pin);
    }
    *gpio_ctrl_0 = tmp;
  } 
  else if(pin <= 63){
    tmp = *gpio_ctrl_1;
    if(is_output){
      tmp|= (1u << (pin-32));
    }
    else{
      tmp&= ~(1u << (pin-32));
    }
    *gpio_ctrl_1 = tmp;
  }
  else if(pin <= 95){
    tmp = *gpio_ctrl_2;
    if(is_output){
      tmp|= (1u << (pin-64));
    }
    else{
      tmp&= ~(1u << (pin-64));
    }
    *gpio_ctrl_2 = tmp;
  }
}

void mt7688_set(int pin, int value)
{
  uint32_t tmp;

  if(pin <= 31){
    tmp = (1u << pin);
    if(value){
      *gpio_dset_0 = tmp;
    }
    else{
      *gpio_dclr_0 = tmp;
    }
  } 
  else if(pin <= 63){
    tmp = (1u << (pin-32));
    if(value){
      *gpio_dset_1 = tmp;
    }
    else{
      *gpio_dclr_1 = tmp;
    }
  } 
  else if(pin <= 95){
    tmp = (1u << (pin-64));
    if(value){
      *gpio_dset_2 = tmp;
    }
    else{
      *gpio_dclr_2 = tmp;
    }
  }
}

static int __init main_init(void)
{
  gpio2_mode = (volatile unsigned long*)ioremap(GPIO2_MODE, 4);
  gpio_ctrl_0 = (volatile unsigned long*)ioremap(GPIO_CTRL_0, 4);
  gpio_ctrl_1 = (volatile unsigned long*)ioremap(GPIO_CTRL_1, 4);
  gpio_ctrl_2 = (volatile unsigned long*)ioremap(GPIO_CTRL_2, 4);
  gpio_data_0 = (volatile unsigned long*)ioremap(GPIO_DATA_0, 4);
  gpio_data_1 = (volatile unsigned long*)ioremap(GPIO_DATA_1, 4);
  gpio_data_2 = (volatile unsigned long*)ioremap(GPIO_DATA_2, 4);
  gpio_dset_0 = (volatile unsigned long*)ioremap(GPIO_DSET_0, 4);
  gpio_dset_1 = (volatile unsigned long*)ioremap(GPIO_DSET_1, 4);
  gpio_dset_2 = (volatile unsigned long*)ioremap(GPIO_DSET_2, 4);
  gpio_dclr_0 = (volatile unsigned long*)ioremap(GPIO_DCLR_0, 4);
  gpio_dclr_1 = (volatile unsigned long*)ioremap(GPIO_DCLR_1, 4);
  gpio_dclr_2 = (volatile unsigned long*)ioremap(GPIO_DCLR_2, 4);
  
  *gpio2_mode = *gpio2_mode | 0x55555555;
  mt7688_dir(0, 0);
  mt7688_dir(1, 0);
  mt7688_dir(2, 0);
  mt7688_dir(3, 0);

  mt7688_dir(14, 1);
  mt7688_dir(15, 1);
  mt7688_dir(43, 1);

  irq = gpio_to_irq(0);
  if(irq < 0){
    printk("failed to gpio_to_irq\n");
  }
  else{
    if(request_irq(irq, isr_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, "gpio-0", NULL) < 0){
      enable_irq(irq);
      printk("failed to request_irq\n");
    }
  }
  return 0;
}
 
static void __exit main_exit(void)
{
  disable_irq(irq);
  free_irq(irq, NULL);
  iounmap(gpio2_mode);
  iounmap(gpio_ctrl_0);
  iounmap(gpio_ctrl_1);
  iounmap(gpio_ctrl_2);
  iounmap(gpio_data_0);
  iounmap(gpio_data_1);
  iounmap(gpio_data_2);
  iounmap(gpio_dset_0);
  iounmap(gpio_dset_1);
  iounmap(gpio_dset_2);
  iounmap(gpio_dclr_0);
  iounmap(gpio_dclr_1);
  iounmap(gpio_dclr_2);
}
 
module_init(main_init);
module_exit(main_exit);


返回上一頁