Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / fbtft / fb_st7735r.c
CommitLineData
735d98cd
TP
1/*
2 * FB driver for the ST7735R LCD Controller
3 *
4 * Copyright (C) 2013 Noralf Tronnes
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
735d98cd
TP
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
79f5da7d 20#include <video/mipi_display.h>
735d98cd
TP
21
22#include "fbtft.h"
23
24#define DRVNAME "fb_st7735r"
afe11f10
CWS
25#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
26 "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
735d98cd 27
735d98cd 28static int default_init_sequence[] = {
79f5da7d 29 -1, MIPI_DCS_SOFT_RESET,
735d98cd
TP
30 -2, 150, /* delay */
31
79f5da7d 32 -1, MIPI_DCS_EXIT_SLEEP_MODE,
735d98cd
TP
33 -2, 500, /* delay */
34
35 /* FRMCTR1 - frame rate control: normal mode
a4f368dc
AJ
36 * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
37 */
c7d85326 38 -1, 0xB1, 0x01, 0x2C, 0x2D,
735d98cd
TP
39
40 /* FRMCTR2 - frame rate control: idle mode
a4f368dc
AJ
41 * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
42 */
c7d85326 43 -1, 0xB2, 0x01, 0x2C, 0x2D,
735d98cd
TP
44
45 /* FRMCTR3 - frame rate control - partial mode
a4f368dc
AJ
46 * dot inversion mode, line inversion mode
47 */
735d98cd
TP
48 -1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
49
50 /* INVCTR - display inversion control
a4f368dc
AJ
51 * no inversion
52 */
735d98cd
TP
53 -1, 0xB4, 0x07,
54
55 /* PWCTR1 - Power Control
a4f368dc
AJ
56 * -4.6V, AUTO mode
57 */
735d98cd
TP
58 -1, 0xC0, 0xA2, 0x02, 0x84,
59
60 /* PWCTR2 - Power Control
a4f368dc
AJ
61 * VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
62 */
735d98cd
TP
63 -1, 0xC1, 0xC5,
64
65 /* PWCTR3 - Power Control
a4f368dc
AJ
66 * Opamp current small, Boost frequency
67 */
735d98cd
TP
68 -1, 0xC2, 0x0A, 0x00,
69
70 /* PWCTR4 - Power Control
a4f368dc
AJ
71 * BCLK/2, Opamp current small & Medium low
72 */
9f8a89e6 73 -1, 0xC3, 0x8A, 0x2A,
735d98cd
TP
74
75 /* PWCTR5 - Power Control */
76 -1, 0xC4, 0x8A, 0xEE,
77
78 /* VMCTR1 - Power Control */
79 -1, 0xC5, 0x0E,
80
79f5da7d 81 -1, MIPI_DCS_EXIT_INVERT_MODE,
735d98cd 82
79f5da7d 83 -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
735d98cd 84
79f5da7d 85 -1, MIPI_DCS_SET_DISPLAY_ON,
735d98cd
TP
86 -2, 100, /* delay */
87
79f5da7d 88 -1, MIPI_DCS_ENTER_NORMAL_MODE,
735d98cd
TP
89 -2, 10, /* delay */
90
91 /* end marker */
c7d85326 92 -3
735d98cd
TP
93};
94
95static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
96{
79f5da7d
PL
97 write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
98 xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
735d98cd 99
79f5da7d
PL
100 write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
101 ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
735d98cd 102
79f5da7d 103 write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
735d98cd
TP
104}
105
e6ea2028
AB
106#define MY BIT(7)
107#define MX BIT(6)
108#define MV BIT(5)
735d98cd
TP
109static int set_var(struct fbtft_par *par)
110{
735d98cd 111 /* MADCTL - Memory data access control
a4f368dc
AJ
112 * RGB/BGR:
113 * 1. Mode selection pin SRGB
114 * RGB H/W pin for color filter setting: 0=RGB, 1=BGR
115 * 2. MADCTL RGB bit
116 * RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
117 */
735d98cd
TP
118 switch (par->info->var.rotate) {
119 case 0:
79f5da7d
PL
120 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
121 MX | MY | (par->bgr << 3));
735d98cd
TP
122 break;
123 case 270:
79f5da7d
PL
124 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
125 MY | MV | (par->bgr << 3));
735d98cd
TP
126 break;
127 case 180:
79f5da7d
PL
128 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
129 par->bgr << 3);
735d98cd
TP
130 break;
131 case 90:
79f5da7d
PL
132 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
133 MX | MV | (par->bgr << 3));
735d98cd
TP
134 break;
135 }
136
137 return 0;
138}
139
140/*
a4f368dc
AJ
141 * Gamma string format:
142 * VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
143 * VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
144 */
94c0a544 145#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
735d98cd
TP
146static int set_gamma(struct fbtft_par *par, unsigned long *curves)
147{
9f8a89e6 148 int i, j;
735d98cd 149
735d98cd
TP
150 /* apply mask */
151 for (i = 0; i < par->gamma.num_curves; i++)
152 for (j = 0; j < par->gamma.num_values; j++)
153fe946 153 CURVE(i, j) &= 0x3f;
735d98cd
TP
154
155 for (i = 0; i < par->gamma.num_curves; i++)
156 write_reg(par, 0xE0 + i,
157 CURVE(i, 0), CURVE(i, 1), CURVE(i, 2), CURVE(i, 3),
158 CURVE(i, 4), CURVE(i, 5), CURVE(i, 6), CURVE(i, 7),
159 CURVE(i, 8), CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
9f8a89e6 160 CURVE(i, 12), CURVE(i, 13), CURVE(i, 14), CURVE(i, 15));
735d98cd
TP
161
162 return 0;
163}
164#undef CURVE
165
735d98cd
TP
166static struct fbtft_display display = {
167 .regwidth = 8,
168 .width = 128,
169 .height = 160,
170 .init_sequence = default_init_sequence,
171 .gamma_num = 2,
172 .gamma_len = 16,
173 .gamma = DEFAULT_GAMMA,
174 .fbtftops = {
175 .set_addr_win = set_addr_win,
176 .set_var = set_var,
177 .set_gamma = set_gamma,
178 },
179};
1014c2ce 180
735d98cd
TP
181FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
182
183MODULE_ALIAS("spi:" DRVNAME);
184MODULE_ALIAS("platform:" DRVNAME);
185MODULE_ALIAS("spi:st7735r");
186MODULE_ALIAS("platform:st7735r");
187
188MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
189MODULE_AUTHOR("Noralf Tronnes");
190MODULE_LICENSE("GPL");
This page took 0.25542 seconds and 5 git commands to generate.