linux/drivers/staging/fbtft/fb_ili9341.c
<<
>>
Prefs
   1/*
   2 * FB driver for the ILI9341 LCD display controller
   3 *
   4 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
   5 * For platforms that doesn't support 9-bit, the driver is capable
   6 * of emulating this using 8-bit transfer.
   7 * This is done by transferring eight 9-bit words in 9 bytes.
   8 *
   9 * Copyright (C) 2013 Christian Vogelgsang
  10 * Based on adafruit22fb.c by Noralf Tronnes
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25 */
  26
  27#include <linux/module.h>
  28#include <linux/kernel.h>
  29#include <linux/init.h>
  30#include <linux/delay.h>
  31
  32#include "fbtft.h"
  33
  34#define DRVNAME         "fb_ili9341"
  35#define WIDTH           240
  36#define HEIGHT          320
  37#define TXBUFLEN        (4 * PAGE_SIZE)
  38#define DEFAULT_GAMMA   "1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
  39                        "00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
  40
  41
  42static int init_display(struct fbtft_par *par)
  43{
  44        fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
  45
  46        par->fbtftops.reset(par);
  47
  48        /* startup sequence for MI0283QT-9A */
  49        write_reg(par, 0x01); /* software reset */
  50        mdelay(5);
  51        write_reg(par, 0x28); /* display off */
  52        /* --------------------------------------------------------- */
  53        write_reg(par, 0xCF, 0x00, 0x83, 0x30);
  54        write_reg(par, 0xED, 0x64, 0x03, 0x12, 0x81);
  55        write_reg(par, 0xE8, 0x85, 0x01, 0x79);
  56        write_reg(par, 0xCB, 0x39, 0X2C, 0x00, 0x34, 0x02);
  57        write_reg(par, 0xF7, 0x20);
  58        write_reg(par, 0xEA, 0x00, 0x00);
  59        /* ------------power control-------------------------------- */
  60        write_reg(par, 0xC0, 0x26);
  61        write_reg(par, 0xC1, 0x11);
  62        /* ------------VCOM --------- */
  63        write_reg(par, 0xC5, 0x35, 0x3E);
  64        write_reg(par, 0xC7, 0xBE);
  65        /* ------------memory access control------------------------ */
  66        write_reg(par, 0x3A, 0x55); /* 16bit pixel */
  67        /* ------------frame rate----------------------------------- */
  68        write_reg(par, 0xB1, 0x00, 0x1B);
  69        /* ------------Gamma---------------------------------------- */
  70        /* write_reg(par, 0xF2, 0x08); */ /* Gamma Function Disable */
  71        write_reg(par, 0x26, 0x01);
  72        /* ------------display-------------------------------------- */
  73        write_reg(par, 0xB7, 0x07); /* entry mode set */
  74        write_reg(par, 0xB6, 0x0A, 0x82, 0x27, 0x00);
  75        write_reg(par, 0x11); /* sleep out */
  76        mdelay(100);
  77        write_reg(par, 0x29); /* display on */
  78        mdelay(20);
  79
  80        return 0;
  81}
  82
  83static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
  84{
  85        fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
  86                "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
  87
  88        /* Column address set */
  89        write_reg(par, 0x2A,
  90                (xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
  91
  92        /* Row address set */
  93        write_reg(par, 0x2B,
  94                (ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
  95
  96        /* Memory write */
  97        write_reg(par, 0x2C);
  98}
  99
 100#define MEM_Y   (7) /* MY row address order */
 101#define MEM_X   (6) /* MX column address order */
 102#define MEM_V   (5) /* MV row / column exchange */
 103#define MEM_L   (4) /* ML vertical refresh order */
 104#define MEM_H   (2) /* MH horizontal refresh order */
 105#define MEM_BGR (3) /* RGB-BGR Order */
 106static int set_var(struct fbtft_par *par)
 107{
 108        fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
 109
 110        switch (par->info->var.rotate) {
 111        case 0:
 112                write_reg(par, 0x36, (1 << MEM_X) | (par->bgr << MEM_BGR));
 113                break;
 114        case 270:
 115                write_reg(par, 0x36,
 116                        (1<<MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
 117                break;
 118        case 180:
 119                write_reg(par, 0x36, (1 << MEM_Y) | (par->bgr << MEM_BGR));
 120                break;
 121        case 90:
 122                write_reg(par, 0x36, (1 << MEM_Y) | (1 << MEM_X) |
 123                                     (1 << MEM_V) | (par->bgr << MEM_BGR));
 124                break;
 125        }
 126
 127        return 0;
 128}
 129
 130/*
 131  Gamma string format:
 132    Positive: Par1 Par2 [...] Par15
 133    Negative: Par1 Par2 [...] Par15
 134*/
 135#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
 136static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 137{
 138        int i;
 139
 140        fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
 141
 142        for (i = 0; i < par->gamma.num_curves; i++)
 143                write_reg(par, 0xE0 + i,
 144                        CURVE(i, 0), CURVE(i, 1), CURVE(i, 2),
 145                        CURVE(i, 3), CURVE(i, 4), CURVE(i, 5),
 146                        CURVE(i, 6), CURVE(i, 7), CURVE(i, 8),
 147                        CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
 148                        CURVE(i, 12), CURVE(i, 13), CURVE(i, 14));
 149
 150        return 0;
 151}
 152#undef CURVE
 153
 154
 155static struct fbtft_display display = {
 156        .regwidth = 8,
 157        .width = WIDTH,
 158        .height = HEIGHT,
 159        .txbuflen = TXBUFLEN,
 160        .gamma_num = 2,
 161        .gamma_len = 15,
 162        .gamma = DEFAULT_GAMMA,
 163        .fbtftops = {
 164                .init_display = init_display,
 165                .set_addr_win = set_addr_win,
 166                .set_var = set_var,
 167                .set_gamma = set_gamma,
 168        },
 169};
 170FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display);
 171
 172MODULE_ALIAS("spi:" DRVNAME);
 173MODULE_ALIAS("platform:" DRVNAME);
 174MODULE_ALIAS("spi:ili9341");
 175MODULE_ALIAS("platform:ili9341");
 176
 177MODULE_DESCRIPTION("FB driver for the ILI9341 LCD display controller");
 178MODULE_AUTHOR("Christian Vogelgsang");
 179MODULE_LICENSE("GPL");
 180