summaryrefslogtreecommitdiff
path: root/drivers/staging/fbtft/fb_ili9340.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 11:30:39 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 11:30:39 -0800
commit46f7b635569731ff81a3b72d1bcd4415b293b637 (patch)
treee97e5e28d1768bb281116d92292851758ea20024 /drivers/staging/fbtft/fb_ili9340.c
parent9682ec9692e5ac11c6caebd079324e727b19e7ce (diff)
parent533e80b1ea709577ec5cf73b8b566569bc711259 (diff)
Merge tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging drivers patches from Greg KH: "Here's the big staging driver tree update for 3.20-rc1. Lots of little things in here, adding up to lots of overall cleanups. The IIO driver updates are also in here as they cross the staging tree boundry a lot. I2O has moved into staging as well, as a plan to drop it from the tree eventually as that's a dead subsystem. All of this has been in linux-next with no reported issues for a while" * tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (740 commits) staging: lustre: lustre: libcfs: define symbols as static staging: rtl8712: Do coding style cleanup staging: lustre: make obd_updatemax_lock static staging: rtl8188eu: core: switch with redundant cases staging: rtl8188eu: odm: conditional setting with no effect staging: rtl8188eu: odm: condition with no effect staging: ft1000: fix braces warning staging: sm7xxfb: fix remaining CamelCase staging: sm7xxfb: fix CamelCase staging: rtl8723au: multiple condition with no effect - if identical to else staging: sm7xxfb: make smtc_scr_info static staging/lustre/mdc: Initialize req in mdc_enqueue for !it case staging/lustre/clio: Do not allow group locks with gid 0 staging/lustre/llite: don't add to page cache upon failure staging/lustre/llite: Add exception entry check after radix_tree staging/lustre/libcfs: protect kkuc_groups from write access staging/lustre/fld: refer to MDT0 for fld lookup in some cases staging/lustre/llite: Solve a race to access lli_has_smd in read case staging/lustre/ptlrpc: hold rq_lock when modify rq_flags staging/lustre/lnet: portal spreading rotor should be unsigned ...
Diffstat (limited to 'drivers/staging/fbtft/fb_ili9340.c')
-rw-r--r--drivers/staging/fbtft/fb_ili9340.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c
new file mode 100644
index 000000000000..985687d94ec2
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9340.c
@@ -0,0 +1,163 @@
+/*
+ * FB driver for the ILI9340 LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME "fb_ili9340"
+#define WIDTH 240
+#define HEIGHT 320
+
+
+/* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */
+static int init_display(struct fbtft_par *par)
+{
+ fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+ par->fbtftops.reset(par);
+
+ write_reg(par, 0xEF, 0x03, 0x80, 0x02);
+ write_reg(par, 0xCF, 0x00 , 0XC1 , 0X30);
+ write_reg(par, 0xED, 0x64 , 0x03 , 0X12 , 0X81);
+ write_reg(par, 0xE8, 0x85 , 0x00 , 0x78);
+ write_reg(par, 0xCB, 0x39 , 0x2C , 0x00 , 0x34 , 0x02);
+ write_reg(par, 0xF7, 0x20);
+ write_reg(par, 0xEA, 0x00 , 0x00);
+
+ /* Power Control 1 */
+ write_reg(par, 0xC0, 0x23);
+
+ /* Power Control 2 */
+ write_reg(par, 0xC1, 0x10);
+
+ /* VCOM Control 1 */
+ write_reg(par, 0xC5, 0x3e, 0x28);
+
+ /* VCOM Control 2 */
+ write_reg(par, 0xC7, 0x86);
+
+ /* COLMOD: Pixel Format Set */
+ /* 16 bits/pixel */
+ write_reg(par, 0x3A, 0x55);
+
+ /* Frame Rate Control */
+ /* Division ratio = fosc, Frame Rate = 79Hz */
+ write_reg(par, 0xB1, 0x00, 0x18);
+
+ /* Display Function Control */
+ write_reg(par, 0xB6, 0x08, 0x82, 0x27);
+
+ /* Gamma Function Disable */
+ write_reg(par, 0xF2, 0x00);
+
+ /* Gamma curve selected */
+ write_reg(par, 0x26, 0x01);
+
+ /* Positive Gamma Correction */
+ write_reg(par, 0xE0,
+ 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1,
+ 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00);
+
+ /* Negative Gamma Correction */
+ write_reg(par, 0xE1,
+ 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1,
+ 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F);
+
+ /* Sleep OUT */
+ write_reg(par, 0x11);
+
+ mdelay(120);
+
+ /* Display ON */
+ write_reg(par, 0x29);
+
+ return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+ fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+ "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+ /* Column address */
+ write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+ /* Row adress */
+ write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+ /* Memory write */
+ write_reg(par, 0x2C);
+}
+
+#define ILI9340_MADCTL_MV 0x20
+#define ILI9340_MADCTL_MX 0x40
+#define ILI9340_MADCTL_MY 0x80
+static int set_var(struct fbtft_par *par)
+{
+ u8 val;
+
+ fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+ switch (par->info->var.rotate) {
+ case 270:
+ val = ILI9340_MADCTL_MV;
+ break;
+ case 180:
+ val = ILI9340_MADCTL_MY;
+ break;
+ case 90:
+ val = ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX;
+ break;
+ default:
+ val = ILI9340_MADCTL_MX;
+ break;
+ }
+ /* Memory Access Control */
+ write_reg(par, 0x36, val | (par->bgr << 3));
+
+ return 0;
+}
+
+
+static struct fbtft_display display = {
+ .regwidth = 8,
+ .width = WIDTH,
+ .height = HEIGHT,
+ .fbtftops = {
+ .init_display = init_display,
+ .set_addr_win = set_addr_win,
+ .set_var = set_var,
+ },
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9340", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9340");
+MODULE_ALIAS("platform:ili9340");
+
+MODULE_DESCRIPTION("FB driver for the ILI9340 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");