LinkIt Smart MT7688 >> C/C++

2.0" IPS 320x240(ILI9335)(Register)


driver/gpio/ili9335_reg/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 <asm/io.h>
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steward_Fu");
MODULE_DESCRIPTION("ILI9335 SLCD Driver for MT7688");

#define gpio_reg_set(buf, pin) buf[pin >> 5]|= (1u << (pin % 32))
#define gpio_reg_clr(buf, pin) buf[(pin >> 5) + 3]|= (1u << (pin % 32))
#define reg_assign(val, buf, pin) \
  if(val){ \
    gpio_reg_set(buf, pin); \
  } \
  else{ \
    gpio_reg_clr(buf, pin); \
  }

#define GPIO1_MODE_ADDR   0x10000060
#define GPIO2_MODE_ADDR   0x10000064
#define GPIO_CTRL_0_ADDR  0x10000600
#define GPIO_CTRL_1_ADDR  0x10000604
#define GPIO_CTRL_2_ADDR  0x10000608
#define GPIO_DATA_0_ADDR  0x10000620
#define GPIO_DATA_1_ADDR  0x10000624
#define GPIO_DATA_2_ADDR  0x10000628
#define GPIO_DSET_0_ADDR  0x10000630
#define GPIO_DSET_1_ADDR  0x10000634
#define GPIO_DSET_2_ADDR  0x10000638
#define GPIO_DCLR_0_ADDR  0x10000640
#define GPIO_DCLR_1_ADDR  0x10000644
#define GPIO_DCLR_2_ADDR  0x10000648

#define GPIO1_MODE_INDEX   0
#define GPIO2_MODE_INDEX  1
#define GPIO_CTRL_0_INDEX  2
#define GPIO_CTRL_1_INDEX  3
#define GPIO_CTRL_2_INDEX  4
#define GPIO_DATA_0_INDEX  5
#define GPIO_DATA_1_INDEX  6
#define GPIO_DATA_2_INDEX  7
#define GPIO_DSET_0_INDEX  8
#define GPIO_DSET_1_INDEX  9
#define GPIO_DSET_2_INDEX  10
#define GPIO_DCLR_0_INDEX  11
#define GPIO_DCLR_1_INDEX  12
#define GPIO_DCLR_2_INDEX  13

#define ILI9335_SLCD_D17   16
#define ILI9335_SLCD_D16   17
#define ILI9335_SLCD_D15   19
#define ILI9335_SLCD_D14   18
#define ILI9335_SLCD_D13   6
#define ILI9335_SLCD_D12   4
#define ILI9335_SLCD_D11   5
#define ILI9335_SLCD_D10   12

#define ILI9335_SLCD_RS    13
#define ILI9335_SLCD_RST   45
#define ILI9335_SLCD_CS    46
#define ILI9335_SLCD_RD    44
#define ILI9335_SLCD_WR    37

static int g_blink_period=1000;
static struct timer_list g_blink_timer;
static volatile unsigned long *gpio_reg[14]={0};

static unsigned int gpio_get(int pin)
{
  return (*gpio_reg[GPIO_DATA_0_INDEX + (pin >> 5)] >> (pin % 32)) & 1u;
}

static void gpio_dir(int pin, int is_output)
{
  if(is_output){
    *gpio_reg[GPIO_CTRL_0_INDEX + (pin >> 5)]|= (1u << (pin % 32));
  }
  else{
    *gpio_reg[GPIO_CTRL_0_INDEX + (pin >> 5)]&= ~(1u << (pin % 32));
  }
}

static void gpio_set(int pin, int value)
{
  if(value){
    *gpio_reg[GPIO_DSET_0_INDEX + (pin >> 5)] = (1u << (pin % 32));
  }
  else{
    *gpio_reg[GPIO_DCLR_0_INDEX + (pin >> 5)] = (1u << (pin % 32));
  }
}

static void ili9335_reset(void)
{
  gpio_set(ILI9335_SLCD_RST, 1);  
  mdelay(100);
  gpio_set(ILI9335_SLCD_RST, 0);
  mdelay(100);  
  gpio_set(ILI9335_SLCD_RST, 1);  
  mdelay(100);
}

static void ili9335_send_command(unsigned int val)
{
  unsigned char i, cmd=0;
  unsigned int reg[6]={0};

  gpio_set(ILI9335_SLCD_RS, 0);
  gpio_set(ILI9335_SLCD_RD, 1);
  gpio_set(ILI9335_SLCD_CS, 0);
  for(i=0; i<2; i++){
    reg[0] = 0;
    reg[3] = 0;
    cmd = (i == 0) ? (val >> 8) : val;
    reg_assign(cmd & 0x01, reg, ILI9335_SLCD_D10);
    reg_assign(cmd & 0x02, reg, ILI9335_SLCD_D11);
    reg_assign(cmd & 0x04, reg, ILI9335_SLCD_D12);
    reg_assign(cmd & 0x08, reg, ILI9335_SLCD_D13);
    reg_assign(cmd & 0x10, reg, ILI9335_SLCD_D14);
    reg_assign(cmd & 0x20, reg, ILI9335_SLCD_D15);
    reg_assign(cmd & 0x40, reg, ILI9335_SLCD_D16);
    reg_assign(cmd & 0x80, reg, ILI9335_SLCD_D17);
    *gpio_reg[GPIO_DSET_0_INDEX] = reg[0];
    *gpio_reg[GPIO_DCLR_0_INDEX] = reg[3];

    gpio_set(ILI9335_SLCD_WR, 0);
    gpio_set(ILI9335_SLCD_WR, 1);
  }
  gpio_set(ILI9335_SLCD_CS, 1);
}

static void ili9335_send_data(unsigned int val)
{
  unsigned char i, dat=0;
  unsigned long reg[6]={0};

  gpio_set(ILI9335_SLCD_RS, 1);
  gpio_set(ILI9335_SLCD_RD, 1);
  gpio_set(ILI9335_SLCD_CS, 0);
  for(i=0; i<2; i++){
    reg[0] = 0;
    reg[3] = 0;
    dat = (i == 0) ? (val >> 8) : val;
    reg_assign(dat & 0x01, reg, ILI9335_SLCD_D10);
    reg_assign(dat & 0x02, reg, ILI9335_SLCD_D11);
    reg_assign(dat & 0x04, reg, ILI9335_SLCD_D12);
    reg_assign(dat & 0x08, reg, ILI9335_SLCD_D13);
    reg_assign(dat & 0x10, reg, ILI9335_SLCD_D14);
    reg_assign(dat & 0x20, reg, ILI9335_SLCD_D15);
    reg_assign(dat & 0x40, reg, ILI9335_SLCD_D16);
    reg_assign(dat & 0x80, reg, ILI9335_SLCD_D17);
    *gpio_reg[GPIO_DSET_0_INDEX] = reg[0];
    *gpio_reg[GPIO_DCLR_0_INDEX] = reg[3];
    gpio_set(ILI9335_SLCD_WR, 0);
    gpio_set(ILI9335_SLCD_WR, 1);
  }
  gpio_set(ILI9335_SLCD_CS, 1);
}

static void ili9335_send_register(unsigned int cmd, unsigned int data)
{
  ili9335_send_command(cmd);
  ili9335_send_data(data);
}

static void ili9335_init(void)
{
  ili9335_send_register(0x0001, 0x0100);
  ili9335_send_register(0x0002, 0x0200);
  ili9335_send_register(0x0003, 0x1018);
  ili9335_send_register(0x0008, 0x0202);
  ili9335_send_register(0x0009, 0x0000);
  ili9335_send_register(0x000A, 0x0000);
  ili9335_send_register(0x000C, 0x0000);
  ili9335_send_register(0x000D, 0x0000);
  ili9335_send_register(0x0060, 0x2700);  
  ili9335_send_register(0x0061, 0x0000);
  ili9335_send_register(0x006A, 0x0000);
  mdelay(10);
  ili9335_send_register(0x0010, 0x1490);
  ili9335_send_register(0x0011, 0x0227);
  mdelay(80);
  ili9335_send_register(0x0012, 0x000c);
  mdelay(10);
  ili9335_send_register(0x0013, 0x1000);
  ili9335_send_register(0x0029, 0x000b);
  ili9335_send_register(0x002b, 0x000b);
  mdelay(10);
  ili9335_send_register(0x0020, 0x0000);
  ili9335_send_register(0x0021, 0x0000);
  
  ili9335_send_register(0x0030, 0x0000);
  ili9335_send_register(0x0031, 0x0406);
  ili9335_send_register(0x0032, 0x0002);
  ili9335_send_register(0x0035, 0x0402);
  ili9335_send_register(0x0036, 0x0004);
  ili9335_send_register(0x0037, 0x0507);
  ili9335_send_register(0x0038, 0x0103);
  ili9335_send_register(0x0039, 0x0707);
  ili9335_send_register(0x003c, 0x0204);
  ili9335_send_register(0x003d, 0x0004);
  
  ili9335_send_register(0x0050, 0x0000);
  ili9335_send_register(0x0051, 0x00ef);
  ili9335_send_register(0x0052, 0x0000);
  ili9335_send_register(0x0053, 0x013f);

  mdelay(10);
  ili9335_send_register(0x0007, 0x0133);  
}

static void show_color(unsigned int val)
{
  int i, j;

  ili9335_send_command(0x0022);
  for(i=0; i<240; i++){
    for(j=0; j<320; j++){
      ili9335_send_data(val);
    }
  }
}

void blink_handler(unsigned long unused)
{
#if 0
  unsigned int in;
  static bool on = false;
  static unsigned int scan=0;
  static unsigned int val=0;
    
  on = !on;
  gpio_set(44, on ? 1 : 0);
  switch(scan){
  case 0:
    gpio_set(14, 0);
    gpio_set(15, 1);
    gpio_set(43, 1);
    in = (gpio_get(0) << 0);
    in|= (gpio_get(1) << 1);
    in|= (gpio_get(2) << 2);
    in|= (gpio_get(3) << 3);
    in<<= 0;
    val&= 0xff0;
    val|= in;
    break;
  case 1:
    gpio_set(14, 1);
    gpio_set(15, 0);
    gpio_set(43, 1);
    in = (gpio_get(0) << 0);
    in|= (gpio_get(1) << 1);
    in|= (gpio_get(2) << 2);
    in|= (gpio_get(3) << 3);
    in<<= 4;
    val&= 0xf0f;
    val|= in;
    break;
  case 2:
    gpio_set(14, 1);
    gpio_set(15, 1);
    gpio_set(43, 0);
    in = (gpio_get(0) << 0);
    in|= (gpio_get(1) << 1);
    in|= (gpio_get(2) << 2);
    in|= (gpio_get(3) << 3);
    in<<= 8;
    val&= 0x0ff;
    val|= in;
     printk("input: 0x%X\n", val);
    break;
  }
  scan+= 1;
  if(scan >= 3){
    scan = 0;
  }
#else
  static int i=0;
  unsigned long col[]={0xf800, 0x7e0, 0x1f};
  show_color(col[i++ % 3]);
#endif
  mod_timer(&g_blink_timer, jiffies + msecs_to_jiffies(g_blink_period));
}

static int __init main_init(void)
{
  unsigned int i;
  unsigned long reg_base[]={
    GPIO1_MODE_ADDR,
    GPIO2_MODE_ADDR,
    GPIO_CTRL_0_ADDR,
    GPIO_CTRL_1_ADDR,
    GPIO_CTRL_2_ADDR,
    GPIO_DATA_0_ADDR,
    GPIO_DATA_1_ADDR,
    GPIO_DATA_2_ADDR,
    GPIO_DSET_0_ADDR,
    GPIO_DSET_1_ADDR,
    GPIO_DSET_2_ADDR,
    GPIO_DCLR_0_ADDR,
    GPIO_DCLR_1_ADDR,
    GPIO_DCLR_2_ADDR,
  };

  for(i=0; i<14; i++){
    gpio_reg[i] = (volatile unsigned long*)ioremap(reg_base[i], 4);
  }

  *gpio_reg[GPIO1_MODE_INDEX]&= 0xffff0fff;
  *gpio_reg[GPIO1_MODE_INDEX]|= 0x51550555;
  *gpio_reg[GPIO2_MODE_INDEX] = 0x55555555;

  gpio_dir(0, 0);
  gpio_dir(1, 0);
  gpio_dir(2, 0);
  gpio_dir(3, 0);
  gpio_dir(14, 1);
  gpio_dir(15, 1);
  gpio_dir(43, 1);

  gpio_dir(37, 1);
  gpio_dir(44, 1);
  gpio_dir(46, 1);
  gpio_dir(45, 1);
  gpio_dir(13, 1);
  gpio_dir(12, 1);
  gpio_dir(5, 1);
  gpio_dir(4, 1);
  gpio_dir(6, 1);
  gpio_dir(18, 1);
  gpio_dir(19, 1);
  gpio_dir(17, 1);
  gpio_dir(16, 1);

  ili9335_reset();
  ili9335_init();
  
  setup_timer(&g_blink_timer, blink_handler, 0);
  mod_timer(&g_blink_timer, jiffies + msecs_to_jiffies(g_blink_period));
  return 0;
}
 
static void __exit main_exit(void)
{
  unsigned int i;

  del_timer(&g_blink_timer);
  for(i=0; i<14; i++){
    iounmap(gpio_reg[i]);
  }
}
 
module_init(main_init);
module_exit(main_exit);

完成


返回上一頁